MySQL IN子句使用子选择与值列表

我需要对一些相关数据进行两个级别的过滤.第一个查询类似于:

SELECT t1.fk_id 
FROM t1 
LEFT JOIN t3 ON t3.fk_id = t1.fk_id
WHERE t1.field1 > 10 AND t3.field2 = Y

第二个查询针对具有相同fk_id字段的另一个表运行,看起来像

SELECT t2.fk_id, SUM(t2.field3) AS sum_3, SUM(t2.field_4) AS sum_4 
FROM t2 
WHERE fk_id IN (fk_values_from_query_1)
GROUP BY t2.fk_id
HAVING sum_3 > 1000

现在,我可以说出两种不同的运行方式-尽管我不受任何一种方法的束缚,但也对其他方法开放.我可以将第一个查询作为SUB-SELECT嵌入到第二个查询中,从性能的角度来看,这确实很糟糕.或者,我可以从查询1的结果中提取值,并将它们作为列表嵌入到查询2中(在我的应用程序代码中).

这个问题的两个部分是:

>在性能方面,上述两种查询结构之间是否有区别?
>有没有更好的方法来构造这两个查询?

基准测试

我没有对此进行全面测试,但是针对我的数据运行了我的版本以及Barmar发布的版本.我的查询运行了大约4.23秒,而Barmar的版本仅运行了0.60秒.这是85%的改善!

解决方法:

您应该使用JOIN组合它们:

SELECT t2.fk_id, SUM(t2.field3) AS sum_3, SUM(t2.field_4) AS sum_4 
FROM t2
JOIN (SELECT distinct t1.fk_id
      FROM t1
      JOIN t2 ON t3.fk_id = t1.fk_id
      WHERE t1.field1 > 10 AND t3.field2 = 'Y') t4
ON t2.fk_id = t4.fk_id
GROUP BY t2.fk_id
HAVING sum_3 > 1000

我一直发现,与类似的连接相比,MySQL在WHERE col IN(子查询)查询上的表现非常糟糕.我没有将它与替换子查询中的值的查询进行比较,因为我只是在无法在单个查询中完成的情况下才这样做(例如,我需要在不同服务器上匹配数据).

顺便说一句,如果您还要过滤与之连接的表中的值,则使用LEFT JOIN没有意义.

在所有情况下,请确保在join或IN子句中使用的键上具有索引.

上一篇:一次迭代两个大数组


下一篇:javascript-更好地检查未定义的属性或设置为null?