mysql解释左边加入表的地方慢点

时间:2015-05-23 23:31:29

标签: mysql performance sql-execution-plan

使用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

我用1M行为两个表提供了数据。

我正在运行的查询:

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

结果:

enter image description here

问题一:

不应该是额外的角色:“使用索引”而不是“where”?

问题二:

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

enter image description here

Tim回答后编辑:

enter image description here

  1. 使用union no时,我猜的文件排序行为是正常的吗?
  2. 为什么在第二行解释中有'使用位置'?如果在第三个是'使用哪里,使用索引'?
  3. 如果您选择从选择中返回多少行,您认为这会变慢?
  4. 联合选择似乎超快,但目前每个选择只返回几行。我将尝试在每个选择中选择更多行。

1 个答案:

答案 0 :(得分:0)

如果您在不同的列上有“OR”,则mysql可能不使用任何索引。

通常我们可以使用“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

但是,在您的情况下,如果任一查询返回大量记录,这可能无济于事。

您的状态列被定义为文本,这可能导致文件排序。您可以将其检查为长varchar,以查看filesort是否正常运行。或者尝试这样做以避免更糟糕的情况:

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