我有以下表格
我必须运行此查询才能获取项目
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')
以上查询需要13秒才能获得1056870行
现在,如果我单独拆分每个查询而不是连接,则需要更少的时间
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
为了使连接查询运行得比单个查询的总时间更快,我必须对连接查询进行哪些更改?
请帮忙。
谢谢你,
萨钦
答案 0 :(得分:0)
您的查询格式为(重新格式化):
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
表格的users
列上的eq文字
user_id
表的locations
列的eq参考
eq ref 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>
来获取查询执行计划。
答案 1 :(得分:0)
一个更好的例子是,如果你想运行一个涉及两组数据交集的查询,这些数据在某种程度上是独立的数据部分...例如,如果你有一个事件表,那么事件就有EventTypes和EventTypes有一个属性“仅限单打”。然后你有一个Users表,用户有MaritalStatus,MaritalStatus有一个标志“Single”。您当然也有一个Attending表将事件映射到用户。
如果你想知道是否有任何非单身人士报名参加你的单打活动,那么正确的答案不是写一个通过ID将这些表连接在一起的查询,然后在where子句中对其进行排序。最好得到一个结果是UserTypes不是单一的用户,JOIN结果是Attending JOINED到一个Select只选择EventTypes只有Singles的事件。以这种方式格式化意味着考勤表周围的JOIN不会加入和返回单个用户,并且不匹配仅非单身人士的事件。