+ -
当前位置:首页 → 问答吧 → MySQL like查询索引无效的原因

MySQL like查询索引无效的原因

时间:2011-07-28

来源:互联网

我自己试验时候发现这么一种情况,数据是模拟的,记录数在三十万以上。

表结构:CREATE TABLE t(id integer auto_increment primary key,name varchar(20),phone varchar(20));

索引如下:CREATE INDEX phone_index on t(phone);

模拟数据的存储过程如下:
DELIMITER //
CREATE PROCEDURE p(IN counter INTEGER)
BEGIN 
 DECLARE v INT;
 SET v = 1;
 PREPARE st FROM "INSERT INTO t(name,phone) VALUES(?,?)";
 WHILE v < counter DO
  SET @name = CONCAT("name",v);
  SET @phone = CONCAT("phone",v);
  IF (counter MOD v) = 0 THEN
  SET @phone = null;
  END IF;
  EXECUTE st USING @name,@phone;
  SET v = v + 1;
 END WHILE;
END //
DELIMITER ;

所以里面的数据都是这样的
+----+-------+--------+
| id | name | phone |
+----+-------+--------+
| 1 | name1 | phone1 |
| 2 | name2 | NULL |
| 3 | name3 | phone3 |
| 4 | name4 | phone4 |
| 5 | name1 | phone1 |
| 6 | name2 | NULL |
| 7 | name3 | phone3 |
| 8 | name4 | phone4 |
| 9 | name1 | phone1 |
| 10 | name2 | NULL |
+----+-------+--------+
10 rows in set (0.00 sec)

例一:我的语句是这样的
mysql> explain select id,name,phone from t where phone like 'phone%' \G

按照我的想法这个查询是使用索引的但很不幸的是得到了下面的结果(没有使用索引)
*************************** 1. row ***************************
  id: 1
  select_type: SIMPLE
  table: t
  type: ALL
possible_keys: phone_index
  key: NULL
  key_len: NULL
  ref: NULL
  rows: 303775
  Extra: Using where
1 row in set (0.00 sec)

例二:奇怪的是我执行了下面的一条语句
mysql> explain select id,name,phone from t where phone like 'myphone%' \G
返回结果显示使用了索引。
*************************** 1. row ***************************
  id: 1
  select_type: SIMPLE
  table: t
  type: range
possible_keys: phone_index
  key: phone_index
  key_len: 37
  ref: NULL
  rows: 3
  Extra: Using where
1 row in set (0.00 sec)

直觉告诉我之所以例一没有使用索引是因为数据库中以phone开头的记录数太多,应该在30w以上,而其他的记录数(NULL和以myphone开头的数据)不超过100。

求解释,希望大家分享MySQL索引的注意事项。

一下在贴几个例子

eg1:不以phone开头索引是有效的
mysql> explain select id,name,phone from t where phone like 'sdfsdfsdf%' \G
*************************** 1. row ***************************
  id: 1
  select_type: SIMPLE
  table: t
  type: range
possible_keys: phone_index
  key: phone_index
  key_len: 37
  ref: NULL
  rows: 1
  Extra: Using where
1 row in set (0.00 sec)

eg2:like字句以通配符开头索引是无效的
mysql> explain select id,name,phone from t where phone like '_sdfsdfsdf%' \G
*************************** 1. row ***************************
  id: 1
  select_type: SIMPLE
  table: t
  type: ALL
possible_keys: NULL
  key: NULL
  key_len: NULL
  ref: NULL
  rows: 303775
  Extra: Using where
1 row in set (0.00 sec)

作者: tt361   发布时间: 2011-07-28

LIKE 时只能是 like 'AA%' 这种前端匹配的才能使用索引。

作者: ACMAIN_CHM   发布时间: 2011-07-28