我在加入下面的2个表时遇到问题。我需要的是第一个表中的所有零件,在第二个表中找到了clei OR零件号,并计算了表1中有多少个匹配项。
=================== ===================
table: svi table: svp
=================== ===================
id id
po price
customer clei
clei partNumber
partNumber description
==================== ===================
svi有大约一百万行。 svp大约有2000。这是我正在使用的联接...
SELECT svi.clei,
svi.partNumber,
count(*)
FROM svp svp
INNER JOIN
svi svi
ON (svp.clei = svi.clei)
OR (svp.partNumber = svi.partNumber)
GROUP BY svi.partNumber
该查询要花2分钟多一点的时间才能运行,这似乎很慢。 clei和partNumber在两个表中都被索引。我还能做些什么来加快加入速度?
最佳答案
索引在这里没有太大帮助,因为没有针对常量的WHERE
条件并且由于OR
运算符。
读取svp
表的所有2000行;常量条件减少了从表中读取的行数,但是这里没有这样的条件。
然后,对于这2000行中的每一行,在svi
表的索引中执行一次或两次查找以标识匹配的行。一个用于clei
,如果未成功,则另一个用于partNumber
。或相反亦然。
表clei
上的列partNumber
和svi
上的复合索引在这里无济于事;使用OR
组合条件时会很有帮助。
不使用表svp
上的索引。如果svp
上有一个同时包含clei
和partNumber
列的索引,则MySQL可以决定在此处读取它,因为它包含的数据少于整个表的数据。但是它仍然读取整个索引并处理所有行。它不能使用索引来筛选行,因为svp
上没有筛选。
可能会更糟(读取整个svi
表并使用svp
上的索引进行查找),但是MySQL足够聪明,可以首先处理较小的表。
将EXPLAIN
放在查询前面,将MySQL tells you (in less words)放在我上面试图解释的地方。
就像我在评论中所说的那样,查询是无效的SQL。对于svi.partNumber
的一个值,您可能对svi.clei
具有多个值。 GROUP BY svi.partNumber
子句从表svi
中获得的所有具有相同partNumber
值的行中生成一个输出行。
但是,由于同一clei
的partNumber
有两个或多个不同的值,因此它对于svi.clei
子句中的表达式SELECT
的最终值是不确定的。这意味着,如果您稍后再次运行同一查询,或者在镜像数据库的其他服务器上运行该查询(或在备份数据库然后从备份还原数据库之后),则可以更改它。
如果您只是忘记在svi.clei
子句中添加GROUP BY
,那么这是一个简单的解决方法,但是否则您必须重新考虑您的查询,因为到目前为止,它不会产生您期望的结果。
关于mysql - MySQL超慢内部连接与分组依据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40753431/