2017-08-14 94 views
1

我有两个查询来计算相对较大的表中的行数。为了允许按特定名称进行过滤,我已经将一个较小的表格添加到了它。在几乎相同的查询中性能差异很大

我的第一次尝试产生了查询#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更好的解决方案?

编辑:

Explain Extended for query #1

Explain Extended for query #2

+3

第二个查询是内部联接 – Strawberry

+0

请为这两个查询生成[执行计划信息](https://dev.mysql.com/doc/refman/5.7/en/explain.html),并将它们附加到问题中(只需运行:'EXPLAIN EXTENDED your_query')。 – krokodilko

+0

我已经添加了执行计划信息。 如果第二个是内连接,是否有可能实现左连接的效果而不会影响性能? –

回答

0

运行的每个查询后,立即SHOW $警告将告诉您优化查询执行顺序。为查询#1和查询#2发布SHOW $ WARNINGS应该有助于我们理解为什么查询#2更快。

+0

没有'$'。只是'显示警告;' –