如果您打算無論是cvmls或收服(異或)和應用程序可以確保要麼可能是真實的,但不是兩者,那麼在邏輯上的LEFT JOIN
是不必要的,查詢總是會產生相同的行數。但是,如果兩者都可以在同一行相匹配,那麼請考慮是否要COUNT(*)所有可能的匹配,包括從加入的左側重複]或COUNT(DISTINCT r.list_number)唯一不同的表] :
-- Query 1
SELECT COUNT(*)
FROM feed_RETS AS RETS LEFT JOIN listings
ON listings.statusID IN (1,2,3)
AND ( RETS.list_number = listings.CVMLS
OR RETS.list_number = listings.REIN
)
WHERE RETS.public_status NOT LIKE '%Sold%'
;
-- Query 2 - Is the count the same?
SELECT COUNT(*)
FROM feed_RETS
WHERE public_status NOT LIKE '%Sold%'
;
如果查詢2返回一個不同的計數,那麼請注意列表中有多行記錄被多次計數。如果你不想這樣做,那麼你需要一個不同的計數 - 或者可能是下面的一個改進。
如果查詢是爲了限制由這個連接所有標準返回的行,那麼你就需要一個INNER JOIN
(並且爲了清楚起見可以在ON
標準以及移動到WHERE
條款):
SELECT COUNT(*)
FROM feed_RETS AS RETS INNER JOIN listings
ON ( RETS.list_number = listings.CVMLS
OR RETS.list_number = listings.REIN
)
WHERE listings.statusID IN (1,2,3)
AND RETS.public_status NOT LIKE '%Sold%'
;
您的查詢仍可能有兩個原因(盡我所能來診斷基於一般假設)慢:
- 在
JOIN
標準OR
強制執行全表掃描,因爲優化器不知道使用哪個索引或是否使用任何索引。
- 通配符
%
在比賽串'%Sold%
開始強制執行全表掃描,因爲指數的正常類型由從分欄的內容內置左到右。這樣想按字母順序排列的名單索引:如果你在一個名稱的開頭匹配(「與‘喬’開頭的名稱」),你可以用你的有序列表快速找到匹配的名稱;相反,如果你正在尋找某個名字中間的東西(「名字中帶有」nat「),那麼你的索引對你來說就沒用了。
該查詢實際上可能會更快:
SELECT SUM(CASE
WHEN l_cvmls.cvmls IS NOT NULL OR l_rein.REIN IS NOT NULL
THEN 1
ELSE 0
END
) listing_count
FROM ( feed_RETS AS r LEFT JOIN listings l_cvmls
ON l_cvmls.statusID IN (1,2,3)
AND r.list_number = l_cvmls.CVMLS
) LEFT JOIN listings l_rein ON l_rein.statusID IN (1,2,3)
AND r.list_number = l_rein.REIN
WHERE r.public_status NOT LIKE '%Sold%'
;
如果你能避免'%Sold%'
和使用'Sold%'
相反,查詢可能會更快依然。
沒有解釋計劃,沒有模式細節,沒有統計數據,沒有示例數據和輸出:downvote。 – symcbean