我有两个级别的过滤我需要做一些相关的数据。第一个查询看起来像: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中的列表(在我的应用程序代码中)嵌入。
两个部分对这个问题是:
- 是否有任何差异,性能明智的,上述2层查询结构之间?
- 有没有更好的方法来构造这2个查询?
基准
我没有完全测试,但跑我的版本,并通过Barmar发布的版本,对我的数据。我的查询在大约4.23秒内运行,而Barmar的版本只运行了0.60秒。这是一个85%的改善!
记住性能最好,唯一的答案是:**基准**。您操作的数据类型,MySQL配置以及您所在硬件的属性,它们将对任何查询的性能产生巨大影响。 – tadman 2013-05-06 17:27:34
绝对!但我对这些查询的理论知之甚少,无法知道哪些方法“已知”效率低下。由于我们的数据库没有经过微调,所以“标准理论”可能会涵盖我的案例。 – Elie 2013-05-06 17:31:12
如果您关心速度,则需要进行基准测试。我试过的表面上看起来很荒谬的事情,只是十种不同方法中的一种,但它以某种方式大大超越了所有其他方法。 MySQL是一个不可预知的野兽。如果这两种方法都能产生正确的数据,下一步就是在可能的情况下根据实际生产数据进行测试,或者尽可能使用真实的传真。 – tadman 2013-05-06 17:41:28