mysql 索引使用问题解惑?!

「已注销」 2012-12-26 02:21:13
有个日志表,需要根据 一个datetime类型查询一段时间的数据,这个字段也 加了索引,但查询时候经常有用不到索引的情况出现

CREATE TABLE `data_log` (
`uniqueid` varchar(20) NOT NULL,
`cam_id` varchar(8) default NULL,
`call_date` datetime default NULL,
`status` varchar(6) default NULL,
PRIMARY KEY (`uniqueid`),
KEY `call_date` (`call_date`),
KEY `cam_id` (`cam_id`),
KEY `status` (`status`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8;

insert into data_log values
('100001','cam1','2012-11-14 08:19:40','A'),('100002','cam1','2012-11-14 08:19:40','B'),('100003','cam1','2012-11-15 08:19:40','C')
,('100004','cam1','2012-11-15 08:19:40','D'),('100005','cam2','2012-11-14 08:19:40','A'),('100006','cam2','2012-11-14 08:19:40','A')
,('100007','cam2','2012-11-15 08:19:40','B'),('100008','cam2','2012-11-15 08:19:40','C'),('100009','cam1','2012-11-14 08:19:40','A'),
('100010','cam1','2012-11-15 08:19:40','B'),('100011','cam2','2012-11-15 08:19:40','A'),('100012','cam2','2012-11-14 08:19:40','C'),
('100013','cam1','2012-11-15 08:19:40','A'),('100014','cam2','2012-11-15 08:19:40','D'),('100015','cam1','2012-11-14 08:19:40','D'),
('100016','cam3','2012-11-14 08:19:40','A'),('100017','cam3','2012-11-14 08:19:40','D'),('100018','cam3','2012-11-15 08:19:40','D'),
('100019','cam3','2012-11-15 08:19:40','C'),('100020','cam3','2012-11-14 08:19:40','A'),('100021','cam2','2012-11-14 08:19:40','B'),
('100022','cam3','2012-11-15 08:19:40','B'),('100023','cam1','2012-11-14 08:19:40','C'),('100024','cam4','2012-11-14 08:19:40','A'),
('100025','cam4','2012-11-15 08:19:40','B'),('100026','cam4','2012-11-15 08:19:40','B'),('100027','cam4','2012-11-15 08:19:40','C');

//可以使用索引
mysql> EXPLAIN
-> select * from data_log where call_date between '2012-11-14 09:00:00' and '2012-11-14 23:59:59';
+----+-------------+----------+-------+---------------+-----------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+-------+---------------+-----------+---------+------+------+-------------+
| 1 | SIMPLE | data_log | range | call_date | call_date | 5 | NULL | 1 | Using where |
+----+-------------+----------+-------+---------------+-----------+---------+------+------+-------------+
1 row in set (0.00 sec)

//不可以使用索引
mysql> explain select * from data_log where call_date between '2012-11-14 08:00:00' and '2012-11-14 23:59:59';
+----+-------------+----------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | data_log | ALL | call_date | NULL | NULL | NULL | 27 | Using where |
+----+-------------+----------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

如上语句:
第一条 call_date between '2012-11-14 09:00:00' and '2012-11-14 23:59:59' 可以使用索引
第二条 call_date between '2012-11-14 08:00:00' and '2012-11-14 23:59:59' 就不可以使用索引了
小白的问下这是怎么回事呢? 该如何调整可以使用到索引值呢?!
...全文
155 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
「已注销」 2012-12-29
  • 打赏
  • 举报
回复
引用 6 楼 ACMAIN_CHM 的回复:
一般情况下,当MYSQL估计符合条件的记录大于总记录的 30% 的情况下,就会直接使用全表扫描而不再使用索引。
多谢!~ 还有个问题请教下 ,我装了mysql5.5.28 给data_log 表按月分了几个区,再次查询,扫描数是少了,可速度却变慢了,这是咋个情况啊?!难道mysql5.5.28 的查询性能还比不上5.0.9?
rucypli 2012-12-28
  • 打赏
  • 举报
回复
可以强制使用索引 select * from data_log where call_date force index(call_date) between '2012-11-14 08:00:00' and '2012-11-14 23:59:59';
rucypli 2012-12-28
  • 打赏
  • 举报
回复
可以强制使用索引 select * from data_log force index(call_date) where call_date between '2012-11-14 08:00:00' and '2012-11-14 23:59:59';
「已注销」 2012-12-28
  • 打赏
  • 举报
回复
引用 1 楼 bonlog 的回复:
这个,很正常啊。 也不可能每次都index啊。 现在问题的关键是:你为何一定要用到索引值。 你要实现什么??
因为表中数据很多 不使用索引就要全表扫描了 很卡 。 我想实现的是 通过 CALL_DATE 或 CALL_DATE 组合其他字段查询某段时间的记录。条件不固定,但call_date 是必选!~
ACMAIN_CHM 2012-12-28
  • 打赏
  • 举报
回复
一般情况下,当MYSQL估计符合条件的记录大于总记录的 30% 的情况下,就会直接使用全表扫描而不再使用索引。
bonlog 2012-12-28
  • 打赏
  • 举报
回复
这个,很正常啊。 也不可能每次都index啊。 现在问题的关键是:你为何一定要用到索引值。 你要实现什么??
「已注销」 2012-12-28
  • 打赏
  • 举报
回复
引用 4 楼 rucypli 的回复:
可以强制使用索引 select * from data_log where call_date force index(call_date) between '2012-11-14 08:00:00' and '2012-11-14 23:59:59';
多谢,发现个现象,当查询的数据值比较少时,不强制使用索引 也可以应用到。但当数据量超过一定量,我本机测的13万行时候 就会全表扫描了。。 请问这个使用全表还是索引的临界值有参数可以调整吗?! 还发现比较悲催的事。。新装的5.5.28版本查询速度居然没有5.0.9快!~ 太囧了!~

56,681

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧