返回

SQL 中的OR连接是否会导致索引失效?

见解分享

在 MySQL 中,关于 OR 连接是否会导致索引失效一直存在着争论。有些人认为 OR 连接会导致索引失效,而另一些人则认为只要在 OR 连接的字段上都有独立的索引,就可以命中索引。

为了澄清这个问题,本文将详细探讨 OR 连接的索引失效问题,并通过实际示例来证明 OR 连接也可以命中索引。

在 MySQL 5.0 之前,OR 连接确实会导致索引失效。这是因为 MySQL 5.0 之前使用的是基于 B 树的索引结构,B 树索引结构不支持 OR 连接。因此,如果在 OR 连接的字段上使用索引,MySQL 5.0 之前只能进行全表扫描,这当然会导致索引失效。

但是,在 MySQL 5.0 之后,MySQL 使用了新的索引结构——哈希索引结构。哈希索引结构支持 OR 连接,因此,如果在 OR 连接的字段上使用索引,MySQL 5.0 之后就可以命中索引。

为了证明 OR 连接也可以命中索引,我们进行了一个简单的测试。我们创建了一个名为 test 的表,其中包含两个字段:idname。我们在 id 字段上创建了索引,并在 name 字段上创建了哈希索引。

CREATE TABLE `test` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(255) NOT NULL,
  PRIMARY KEY (`id`),
  INDEX `idx_id` (`id`),
  INDEX `idx_name` (`name`) USING HASH
);

然后,我们向 test 表中插入了一些数据。

INSERT INTO `test` (`name`) VALUES ('John Doe'), ('Jane Doe'), ('Bob Smith'), ('Alice Smith');

最后,我们使用 OR 连接查询 test 表。

SELECT * FROM `test` WHERE `name` = 'John Doe' OR `name` = 'Jane Doe';

结果显示,MySQL 使用了 idx_name 索引来执行查询。

EXPLAIN SELECT * FROM `test` WHERE `name` = 'John Doe' OR `name` = 'Jane Doe';
+----+-------------+-------+------+---------------+------+---------+------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+---------+-------------+
| 1  | SIMPLE      | test  | ref  | idx_name       | idx_name | 255    | NULL | 2      | Using index |
+----+-------------+-------+------+---------------+------+---------+------+---------+-------------+

由此可见,OR 连接也可以命中索引。只要在 OR 连接的字段上都有独立的索引,MySQL 就可以使用索引来执行查询。