mysql 解释慢在左边加入的地方 table

mysql explain slow where on left joined table

玩一个mysql,想着以后怎么解决一件事。我想检索由我的朋友(特定用户 ID)发布或在我关注的组内发布的状态。

CREATE TABLE `status` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `status` text COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`),
  KEY `IDX_F23501207E3C61F9` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1567559 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

CREATE TABLE `group_status` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `group_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `IDX_F23501207E3C61F9` (`group_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

我为两个表提供了 100 万行。

查询我是运行:

SELECT s.id, s.status, gs.group_id
FROM status s 
LEFT JOIN group_status gs
ON s.id = gs.id
WHERE 
s.user_id IN (55883,122024,442468,846269,903941,980896,192660,20608,525056,563457)
OR gs.group_id IN (78,79,79,80,80,83,84,85,86,87,88,89,89,91,92,92,94,98)
ORDER BY s.id DESC
LIMIT 15

结果:

问题一:

不应该是像这样的额外角色:"using index" 而不是 "where" ?

问题二:

为什么响应时间这么慢? 2,3s

在蒂姆的回答后编辑:

  1. 我猜在使用 union no 时文件排序行为是正常的?
  2. explain的第二行为什么有'using where'?如果在第三个是 'using where, using index' ?
  3. 如果从 select 返回多少行,您认为这会变慢吗?

联合 select 似乎超级快,但目前只有几行返回每个 select。我将尝试在每个 select 中增加 select 行。

如果您在不同的列上有一个 "OR",mysql 可能会使用您的 none 个索引。

通常我们可以使用 "UNION" 两个单独的查询来解决问题,每个查询都匹配一个条件。

SELECT id, status, group_id FROM
(
  SELECT s.id, s.status, gs.group_id
  FROM status s 
  LEFT JOIN group_status gs
  ON s.id = gs.id
  WHERE 
  s.user_id IN (55883,122024,442468,846269,903941,980896,192660,20608,525056,563457)
UNION 
  SELECT s.id, s.status, gs.group_id
  FROM status s 
  LEFT JOIN group_status gs
  ON s.id = gs.id
  WHERE 
  gs.group_id IN (78,79,79,80,80,83,84,85,86,87,88,89,89,91,92,92,94,98)
) t
ORDER BY id DESC
LIMIT 15

但是,对于您的情况,如果查询 returns 大量记录,这可能无济于事。

您的状态栏被定义为文本,这可能会导致文件排序。您可以将其检查为 long varchar 以查看文件排序是否正常。或者试试这个以避免更坏的情况:

SELECT ss.id, group_id, ss.status 
FROM (
SELECT id, group_id FROM
(
  SELECT s.id,  gs.group_id
  FROM status s 
  LEFT JOIN group_status gs
  ON s.id = gs.id
  WHERE 
  s.user_id IN (55883,122024,442468,846269,903941,980896,192660,20608,525056,563457)
UNION 
  SELECT s.id,  gs.group_id
  FROM status s 
  LEFT JOIN group_status gs
  ON s.id = gs.id
  WHERE 
  gs.group_id IN (78,79,79,80,80,83,84,85,86,87,88,89,89,91,92,92,94,98)
) t
ORDER BY id DESC
LIMIT 15
) f
JOIN status ss
ON f.id =ss.id 
ORDER BY ss.id