我一直在分析我正在处理的应用程序中的一些查询,并且遇到了一个查询,该查询检索的行数多于必要的数量,结果集在应用程序代码中被裁减。左连接优于内连接?
将LEFT JOIN更改为INNER JOIN将结果集修剪为所需内容,并且可能还会更高效(因为选择的行数更少)。事实上,LEFT JOINED的查询表现超过INNER JOIN'ED,花了一半时间完成。
LEFT JOIN:(127点总的行,查询花费0.0011秒)
INNER JOIN:(10点总的行,查询花费0.0024秒)
(我跑的查询多次,并且这些是平均数) 。
运行EXPLAIN上都显示没有任何解释的性能差异:
对于INNER JOIN:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE contacts index NULL name 302 NULL 235 Using where
1 SIMPLE lists eq_ref PRIMARY PRIMARY 4 contacts.list_id 1
1 SIMPLE lists_to_users eq_ref PRIMARY PRIMARY 8 lists.id,const 1
1 SIMPLE tags eq_ref PRIMARY PRIMARY 4 lists_to_users.tag_id 1
1 SIMPLE users eq_ref email_2 email_2 302 contacts.email 1 Using where
对于LEFT JOIN:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE contacts index NULL name 302 NULL 235 Using where
1 SIMPLE lists eq_ref PRIMARY PRIMARY 4 contacts.list_id 1
1 SIMPLE lists_to_users eq_ref PRIMARY PRIMARY 8 lists.id,const 1
1 SIMPLE tags eq_ref PRIMARY PRIMARY 4 lists_to_users.tag_id 1
1 SIMPLE users eq_ref email_2 email_2 302 contacts.email 1
和查询本身:
SELECT `contacts`.*, `lists`.`name` AS `group`, `lists`.`id` AS `group_id`, `lists`.`shared_yn`, `tags`.`name` AS `context`, `tags`.`id` AS `context_id`, `tags`.`color` AS `context_color`, `users`.`id` AS `user_id`, `users`.`avatar`
FROM `contacts`
LEFT JOIN `lists` ON lists.id=contacts.list_id
LEFT JOIN `lists_to_users` ON lists_to_users.list_id=lists.id AND lists_to_users.user_id='1' AND lists_to_users.creator='1'
LEFT JOIN `tags` ON tags.id=lists_to_users.tag_id
INNER JOIN `users` ON users.email=contacts.email
WHERE (contacts.user_id='1')
ORDER BY `contacts`.`name` ASC
(我所说的子句是“用户”表上的最后一个INNER JOIN)
查询在MySQL 5.1数据库上运行,如果它有所不同。
有没有人有一个线索,为什么在这种情况下,LEFT JOIN的查询优于INNER JOIN?
更新:由于Tomalak的建议,我使用的小表使INNER JOIN更复杂,我创建了一个包含一些模拟数据的测试数据库。 “用户”表格为5000行,联系人表格为〜500,000行。结果是一样的(时间也没有改变,当你认为表格现在更大时,这是令人惊讶的)。
我也在联系人表上运行ANALYZE和OPTIMIZE。没有做出任何明显的区别。
您是否尝试先放置内连接? – 2008-10-09 06:10:02
我有,它确实加快了20%的查询速度,但仍然比左加入速度更慢 – 2008-10-09 06:14:43
尝试按顺序构建每个查询(加入一个表,测量,加入下一个等等)也许这可以帮助您确定慢速操作。 – Tomalak 2008-10-09 06:21:48