2017-05-06 82 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)指标。