让我们假设以下简单的情况:
我有两个表,一个类别表,其中包含两个字段CategoryId
和CategoryGroup
,以及一个包含另一个字段的广告表两个字段AdId
和category_CategoryId
,它是指向类别表的链接。
类别表格中的所有行都分为两个不同的组:购买或租借。因此,该表中的每一行都在CategoryGroup
中包含字符串 buy 或字符串 rent 。
假设我想计算出售广告中的广告数量。
我有两种方法可以做到这一点:
执行NOT IN
这样的查询:SELECT COUNT(AdId) as Total FROM ads WHERE category_CategoryId NOT IN (SELECT CategoryId FROM category WHERE CategoryGroup = 'rent')
或者像这样执行'IN'查询:SELECT COUNT(AdId) as Total FROM ads WHERE category_CategoryId IN (SELECT CategoryId FROM category WHERE CategoryGroup = 'buy')
我测试了两个查询,在我看来,NOT IN
查询的执行速度比IN
类型的查询快。
(约{900}表上NOT IN
为0.45秒,约45个类别,同一数据集上IN
为1.1秒
这是偶然的,或者NOT IN
查询在相似的情况下总能执行得更快吗?
答案 0 :(得分:0)
IN ( SELECT ... )
和NOT IN ( SELECT ... )
可能永远是编写内容的最有效方式。一个可能比另一个更快,因为SELECT
的行数少于另一个,而不是NOT
。
假设广告只属于一个类别,这可能是效率最高的。
SELECT Count(ads.AdId) as Total, ads.CategoryId
FROM ads
JOIN category AS c ON c.CategoryId = ads.CategoryId
WHERE c.CategoryGroup = 'buy'
GROUP BY ads.CategoryId
如果某个广告可以分为多个类别,那么您就会有一个难题:是否应该在计数中包含或排除“买入”和“出租”的广告?无论如何,我正准备将IN
替换为EXISTS
作为替代优化:
SELECT Count(AdId) as Total, CategoryId
FROM ads
WHERE EXISTS
( SELECT *
FROM category
WHERE CategoryId = ads.CategoryId
AND CategoryGroup = 'buy'
)
GROUP BY CategoryId
(抱歉,我不能忍受像category_CategoryId
这样不必要的冗余列名。)
对各种选择执行EXPLAIN SELECT ...
以获得更多洞察力。