使用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
结果:
问题一:
不应该是额外的角色:“使用索引”而不是“where”?
问题二:
为什么响应时间这么慢?的 2,3s
Tim回答后编辑:
联合选择似乎超快,但目前每个选择只返回几行。我将尝试在每个选择中选择更多行。
答案 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