2017-05-06 87 views
1

我正在閱讀mysql manual爲什麼使用「或」的示例查詢不使用索引?

以下是手冊中的示例。

示例創建Multiple-Column Indexes,索引是(last_name,first_name)

CREATE TABLE test (
    id   INT NOT NULL, 
    last_name CHAR(30) NOT NULL, 
    first_name CHAR(30) NOT NULL, 
    PRIMARY KEY (id), 
    INDEX name (last_name,first_name) 
); 

手動說,這種查詢將使用索引

SELECT * FROM test 
    WHERE last_name='Widenius' AND first_name='Michael'; 

但低於or查詢將不使用索引:

SELECT * FROM test 
    WHERE last_name='Widenius' OR first_name='Michael'; 

問題

爲什麼例子查詢與or,即爲什麼

SELECT * FROM test 
     WHERE last_name='Widenius' OR first_name='Michael'; 

不使用索引?

+0

你可以通過顯示執行計劃來證明這一點嗎? – Jan

+0

但是,名稱索引不用於以下查詢中的查找:SELECT * FROM test WHERE last_name ='Widenius'OR first_name ='Michael'; –

+0

@Jan手冊說 –

回答

2

只想說,數據庫是不擅長WHERE子句中優化OR(或INNOT IN)的條件。

在很高的層次上,我可能會將原因描述如下。當使用AND連接條件時,第一個縮小用於第二個的人口。這使得索引可行,因爲條件「嵌套」。當使用OR時,條件是獨立的。我應該注意到一些數據庫可以比其他數據庫更好地處理OR條件。

如果您希望您的代碼使用索引,你可以使用UNION ALL

SELECT t.* 
FROM test t 
WHERE last_name = 'Widenius' 
UNION ALL 
SELECT t.* 
FROM test t 
WHERE last_name <> 'Widenius' AND first_name = 'Michael'; 

爲了獲得最佳性能,你想在test(last_name)test(first_name, last_name)指標。