我有两个查询来计算一个相对较大的表中的行数。为了允许按特定名称进行筛选,我已将一个较小的表左联到该表。
我的第一次尝试产生了查询#1(见下文(,结果非常非常慢(6-7秒(。在对查询进行了一会儿之后,我必须查询 #2(见下文(,它似乎可以更快地完成同样的事情(<0.05 秒(。
查询 #1(> 6 秒(:
SELECT COUNT(*)
FROM bigtable
LEFT JOIN (
SELECT DISTINCT LocalKey, Name
FROM smalltable
) AS smalltable ON bigtable.ForeignKey = smalltable.LocalKey;
查询 #2(<0.05 秒(:
SELECT COUNT(*)
FROM bigtable
LEFT JOIN (
SELECT DISTINCT LocalKey, Name
FROM smalltable
) AS smalltable ON bigtable.ForeignKey = smalltable.LocalKey
WHERE smalltable.LocalKey LIKE "%";
两个查询返回完全相同的数字 (50300(。bigtable
有 50300 行,smalltable
有 680 行。为了尽可能多地删除因素,我确保bigtable
中的所有记录在smalltable
中都有一个(唯一(匹配行。smalltable.LocalKey
已编制索引,以及bigtable
的主键。两个表都已使用OPTIMIZE TABLE [table];
进行了优化。smalltable
的所有行都由smalltable.LocalKey LIKE "%"
匹配。
我尝试详尽地搜索这种现象,但是,我没有找到任何解释。有没有人解释为什么第一个查询要慢得多,如果可能的话,比查询#2更好的解决方案?
编辑:
解释 查询 #1 的扩展
解释 查询 #2 的扩展
运行每个查询后,SHOW $WARNINGS 将立即显示优化的查询执行顺序。 发布查询 #1 和查询 #2 的 SHOW $WARNINGS应该有助于我们理解为什么查询 #2 如此之快。