我有下表
用户表
- 列:ID、电子邮件
- 索引:id
位置表
- 列 -> id、名称、user_id、last_scan_time
- 索引:id、user_id
项目表
- 列 -> id、名称、location_id、last_scan_time
- 索引:id、location_id
我必须运行此查询才能获取项目
select items.* from items
inner join locations on (items.last_scan_time = locations.last_scan_time and items.location_id = locations.id)
inner join users on (locations.user_id = users.id and users.email = 'abc@abc.com')
以上查询 1056870 行需要 13 秒
现在,如果我单独拆分每个查询而不是联接,则需要的时间会少得多
select id from users where email = 'abc@abc.com'
0.0 sec
select id,last_scan_time from locations where user_id = #user-id-returned-from-above-query#
0.0 sec
select * from items where last_scan_time = #last_scan_time-from-above-query# and location_id = #location-id-from-above-query#
0.01 sec
我必须对连接查询或索引进行哪些更改才能使连接查询的运行速度快于各个查询的总时间?
请帮忙。
谢谢,
萨钦
最佳答案
您的查询采用以下形式(重新格式化):
SELECT i.*
FROM items i
JOIN locations l
ON l.last_scan_time = i.last_scan_time
AND l.id = i.location_id
JOIN users u
ON u.id = l.user_id
AND u.email = 'abc@abc.com'
基本上,查询中的谓词是:
email
上的 eq 文字users
栏目表eq 引用
user_id
locations
栏目表eq 引用
location_id
和last_scan_time
的items
表
这表明对于这个特定的查询,最佳索引可能类似于:
... ON users (email,id)
... ON locations (id, last_scan_time)
... ON items (location_id, last_scan_time)
但是这个建议实际上取决于实际的表定义,表是MyISAM还是InnoDB,基数和数据分布等等。
我建议您使用EXPLAIN <query>
获取查询执行计划。
关于mysql - 为什么内连接比单独查询慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21771101/