我能想到的幾個方法,每個方法根據索引和特定的數據庫實現執行不同的操作。有些可能看起來很慢的可以通過您可能沒有想象到的方式進行優化,因此值得試用它們並比較執行計劃以瞭解發生了什麼...
注意1:我使用GROUP BY而不是DISTINCT,這是因爲它允許優化器使用索引。我見過的實施工作了,他們可以把DISTINCT到一個GROUP BY,但它在拳頭地方使用GROUP BY可以肯定的是非常值得的。它也讓你思考索引,這絕不是壞事。
注2:一些像這樣的查詢需要一段時間進行優化,因爲有很多選擇的優化器來評估。因此,通常值得編譯所有的不同選項中存儲過程和比較這些存儲過程的執行。這確保您的比較實際上是查詢時間而不是不同的編譯時間。
SELECT
[tree].productID
FROM
products_tree AS [tree]
WHERE
[tree].productID IN (1040,1050,1168)
AND NOT EXISTS (SELECT * FROM products_tree WHERE productID = [tree].productID AND categoryID NOT IN (1040,1050,1168))
GROUP BY
[tree].productID
SELECT
[tree].productID
FROM
products_tree AS [tree]
LEFT OUTER JOIN
(
SELECT
productID
FROM
product_tree
WHERE
productID NOT IN (1040,1050,1168)
GROUP BY
productID
)
AS [ok_products]
ON [ok_products].productID = [tree].productID
WHERE
[tree].productID IN (1040,1050,1168)
AND [ok_products].productID IS NULL
GROUP BY
[tree].productID
SELECT
[tree].productID
FROM
products_tree AS [tree]
GROUP BY
[tree].productID
HAVING
MAX(CASE WHEN [tree].productID IN (1040,1050,1168) THEN 1 ELSE 0 END) = 1
AND MAX(CASE WHEN [tree].productID NOT IN (1040,1050,1168) THEN 1 ELSE 0 END) = 0
還有其他的,每個的變化,但是這應該給你一個很好的開始。但我真的要強調使用GROUP BY和考慮指標:)
產品ID和類別ID都在各自的表中的主,而且INDEX在鏈接表上。 我將DISTINCT更改爲GROUP BY,並獲得了完全相同的性能。我想優化器注意到了這一點。 您在學術上有趣的SQL建議,所以我接受了這個答案。 – rwired 2009-02-13 02:31:00