確實,OR
通常會阻止有效使用索引。處理WHERE
子句時,查詢通常只能使用每個表的一個索引。所以,如果你有一個像
WHERE col1 = 1 OR col2 = 2
的條件它不能使用任何一個索引來查找所有匹配的行。你一般最好是關閉將查詢分爲二,並使用UNION
:
SELECT ...
FROM TABLE
WHERE col1 = 1
UNION
SELECT ...
FROM TABLE
WHERE col2 = 2
不過,我覺得我讀的地方,在簡單的情況下,MySQL是能夠自動完成這一轉變。檢查您的查詢的EXPLAIN
輸出。
但是當OR
條件涉及相同的列時,它仍然可以使用該索引,例如,如果你有
WHERE col1 = 1 OR col1 = 2
它只是查找這兩個索引條目在索引中的col1
。這是當你寫它做什麼:
WHERE col1 IN (1, 2)
然而,查詢比這更復雜,因爲它也與AND
組合多個條件。如果您只是使用=
比較,則可以使用多列索引(例如,
INDEX (type, author_id, post_id)
但是,當你有多個IN
條件,這不能做,因爲它會需要枚舉所有組合。
type = 4 AND author_id IN (1, 2) AND post_id IN (10, 20)
需要查找所有這些索引:
4, 1, 10
4, 1, 20
4, 2, 10
4, 2, 20
我不認爲MySQL會產生這樣所有的組合(但我可能是錯的 - 檢查EXPLAIN
輸出,看看它可以)。
取而代之的是,它會選擇它認爲最有效的索引,使用它來查找與該部分條件匹配的行,並掃描這些行以評估其餘條件。
用'SELECT type,author_id,post_id'替換'DELETE',然後預先加入'EXPLAIN'並使用MySQL客戶端運行查詢。創建你想要的任何索引,'EXPLAIN'查詢將告訴你使用了哪些索引。詳細瞭解['EXPLAIN'輸出]的含義(http://dev.mysql.com/doc/refman/5.7/en/explain-output.html)。 – axiac
基本的經驗法則:添加一個索引到'決定'上下文中使用的任何字段,這是'where','join','order by,'etc ... –
@MarcB好了,有時候我們需要添加一個倍數列索引。例如:'(type,author_id,post_id)'..但是,在這些條件之間存在「AND」時,情況就是如此。我想知道當他們之間有'OR'時我應該怎麼做... –