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)
表结构: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
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28