目前尚不清楚爲什麼要重寫查詢以消除IN列表。該查詢可以被重寫以取代col IN (literal list)
謂詞,但這不會提高性能。
如果您正在尋找提高性能,它更可能你會想消除
NOT EXISTS (correlated_subquery)
謂詞,並使用「反連接」模式取代它,這樣的事情:
SELECT t1.*
FROM kx_examenes_diagnostico.examenes t1
LEFT
JOIN kx_examenes_diagnostico.examenes_aplicados t2
ON t2.examen_id=t1.examen_id
AND t2.alumno_id=812
WHERE t1.examen_id IN (1,2,3,4,5,10,11,12,13,50,159,635,456,780,12,63,45)
AND t2.examen_id IS NULL
「抗連接」模式是一個外連接(包括來自t1
行不具有在t2
任何匹配的行)與predic組合ate(WHERE子句)消除了確實匹配的行。
對於這個特定的查詢的最佳性能,你很可能要指標
... ON examenes (examen_id)
... ON examenes_aplicados (examen_id, alumno_id)
根據alumno_id
列的基數,該指數可能會更好:
... ON examenes_aplicados (alumno_id, examen_id)
無論是那些examenes_aplicados
上的兩個索引是「覆蓋索引」,這意味着MySQL可以通過訪問索引頁滿足查詢,而不需要訪問基礎表中的頁面。我們預計MySQL EXPLAIN
會顯示「Using index
」來訪問該表。
UPDATE:
我避而不答你提出的問題,並回答了完全不同的問題。回答您提問的問題:
問:我必須使用OR嗎?
不,您不必使用OR關鍵字。 IN列表可以替換爲不使用任何OR
關鍵字的等效謂詞。
問:有可能嗎?
是的,可以用EXISTS
子句替代IN (list)
謂詞。但是你做而不是想要這樣做,除非你的目標是可怕的表現,而且你有渴望讓DBA追捕你,懲罰你,公開羞辱你,並且打敗你。
當你有一個常量列表時,'in'很好。性能問題是存在子查詢時。 –
當「IN」子句在主鍵/索引列上選擇時,它幾乎儘可能快,因爲該行可以直接從索引獲得,索引應該可以通過二進制搜索進行排序。 – Smutje
「在」和「存在」不一定做同樣的事情。有兩個時間和一個地方。獲得正確的結果應該是至關重要的。那麼你可以擔心速度。 –