ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

MySQL没有选择正确的索引

2020-04-19 13:03:32  阅读:232  来源: 互联网

标签:NULL 正确 mmmoverttme 索引 sn MySQL mmmtransttme devabce id


发现有个mysql库的cpu使用比较厉害,分析后发现是以下的sql导致:

SELECT
	`devabce`.`id`,
	`devabce`.`sn_id`,
	`devabce`.`mmmcontent`,
	`devabce`.`mmmcommitttme`,
	`devabce`.`mmmtransttme`,
	`devabce`.`mmmoverttme`,
	`devabce`.`mmmreturn`,
	`devabce`.`reserved` 
FROM
	`devabce` 
WHERE
	(
		`devabce`.`sn_id` = 'ADBG182760058' 
		AND ((
				`devabce`.`mmmoverttme` IS NULL 
				AND `devabce`.`mmmtransttme` IS NULL 
				) 
		OR ( `devabce`.`mmmoverttme` IS NULL AND `devabce`.`mmmtransttme` IS NOT NULL AND `devabce`.`mmmtransttme` > '2020-04-18 18:40:40.466628' ))) 
ORDER BY
	`devabce`.`id` ASC
	LIMIT 200;

该语句单次执行时间长达376.424870秒。而且是执行比较频繁的语句。

 

查看该sql的执行计划:

+----+-------------+---------+------------+-------+----------------------------------------------------------+---------+---------+------+-------+----------+-------------+
| id | select_type | table   | partitions | type  | possible_keys                                            | key     | key_len | ref  | rows  | filtered | Extra       |
+----+-------------+---------+------------+-------+----------------------------------------------------------+---------+---------+------+-------+----------+-------------+
|  1 | SIMPLE      | devabce | NULL       | index | devabce_sn_id_c2b22ec1_fk_iclock_sn,idx_snid_ottme_tttme | PRIMARY | 4       | NULL | 59125 |     0.07 | Using where |
+----+-------------+---------+------------+-------+----------------------------------------------------------+---------+---------+------+-------+----------+-------------+

从执行计划可以看到,优化器选择使用了主键。

查看该表,表中有数据2千多万条;索引idx_snid_ottme_tttme是建立在列(sn_id、mmmoverttme、mmmtransttme),而且该索引的选择性很好。按道理应该使用该索引,而不是使用主键。

首先尝试对表analyze,然后再次执行,发现还是使用了主键。索引仍然没有选对。鉴于目前不方便对表执行optimze。就尝试使用hint,看看执行效果。

 

1.使用use index(idx_snid_ottme_tttme)

执行大约0.3秒即可返回数据。执行计划如下:

+----+-------------+---------+------------+-------+----------------------+----------------------+---------+------+-------+----------+---------------------------------------+
| id | select_type | table   | partitions | type  | possible_keys        | key                  | key_len | ref  | rows  | filtered | Extra                                 |
+----+-------------+---------+------------+-------+----------------------+----------------------+---------+------+-------+----------+---------------------------------------+
|  1 | SIMPLE      | devabce | NULL       | range | idx_snid_ottme_tttme | idx_snid_ottme_tttme | 100     | NULL | 84826 |   100.00 | Using index condition; Using filesort |
+----+-------------+---------+------------+-------+----------------------+----------------------+---------+------+-------+----------+---------------------------------------+

  

2.修改原sql,使得不走主键

SELECT
	`devabce`.`id`,
	`devabce`.`sn_id`,
	`devabce`.`mmmcontent`,
	`devabce`.`mmmcommitttme`,
	`devabce`.`mmmtransttme`,
	`devabce`.`mmmoverttme`,
	`devabce`.`mmmreturn`,
	`devabce`.`reserved` 
FROM
	`devabce` 
WHERE
	(
		`devabce`.`sn_id` = 'ADBG182760058' 
		AND ((
				`devabce`.`mmmoverttme` IS NULL 
				AND `devabce`.`mmmtransttme` IS NULL 
				) 
		OR ( `devabce`.`mmmoverttme` IS NULL AND `devabce`.`mmmtransttme` IS NOT NULL AND `devabce`.`mmmtransttme` > '2020-04-18 18:40:40.466628' ))) 
ORDER BY
	`devabce`.`id`+0 ASC
	LIMIT 200;

执行0.3秒即可返回数据,执行计划如下:选对了索引

+----+-------------+---------+------------+-------+----------------------------------------------------------+----------------------+---------+------+-------+----------+---------------------------------------+
| id | select_type | table   | partitions | type  | possible_keys                                            | key                  | key_len | ref  | rows  | filtered | Extra                                 |
+----+-------------+---------+------------+-------+----------------------------------------------------------+----------------------+---------+------+-------+----------+---------------------------------------+
|  1 | SIMPLE      | devabce | NULL       | range | devabce_sn_id_c2b22ec1_fk_iclock_sn,idx_snid_ottme_tttme | idx_snid_ottme_tttme | 100     | NULL | 84826 |   100.00 | Using index condition; Using filesort |
+----+-------------+---------+------------+-------+----------------------------------------------------------+----------------------+---------+------+-------+----------+---------------------------------------+

  

3.使用IGNORE INDEX(PRIMARY)

SELECT
	`devabce`.`id`,
	`devabce`.`sn_id`,
	`devabce`.`mmmcontent`,
	`devabce`.`mmmcommitttme`,
	`devabce`.`mmmtransttme`,
	`devabce`.`mmmoverttme`,
	`devabce`.`mmmreturn`,
	`devabce`.`reserved` 
FROM
	`devabce` IGNORE INDEX(PRIMARY)
WHERE
	(
		`devabce`.`sn_id` = 'ADBG182760058' 
		AND ((
				`devabce`.`mmmoverttme` IS NULL 
				AND `devabce`.`mmmtransttme` IS NULL 
				) 
		OR ( `devabce`.`mmmoverttme` IS NULL AND `devabce`.`mmmtransttme` IS NOT NULL AND `devabce`.`mmmtransttme` > '2020-04-18 18:40:40.466628' ))) 
ORDER BY
	`devabce`.`id` ASC
	LIMIT 200;

执行了大约4秒,从执行计划看,虽然没有使用主键,但是仍然选错了索引

+----+-------------+---------+------------+-------+----------------------------------------------------------+-------------------------------------+---------+------+--------+----------+------------------------------------+
| id | select_type | table   | partitions | type  | possible_keys                                            | key                                 | key_len | ref  | rows   | filtered | Extra                              |
+----+-------------+---------+------------+-------+----------------------------------------------------------+-------------------------------------+---------+------+--------+----------+------------------------------------+
|  1 | SIMPLE      | devabce | NULL       | range | devabce_sn_id_c2b22ec1_fk_iclock_sn,idx_snid_ottme_tttme | devabce_sn_id_c2b22ec1_fk_iclock_sn | 82      | NULL | 429784 |     3.97 | Using index condition; Using where |
+----+-------------+---------+------------+-------+----------------------------------------------------------+-------------------------------------+---------+------+--------+----------+------------------------------------+

删除索引devabce_sn_id_c2b22ec1_fk_iclock_sn,再次测试上面的语句,就可以选对索引了。

 

针对mysql不能选对正确索引,查了一下官方信息,发现有个类似的bug:

暂时怀疑是该bug所导致。

 

因为不是自己的库,还得等待下周同事来确认。

 

标签:NULL,正确,mmmoverttme,索引,sn,MySQL,mmmtransttme,devabce,id
来源: https://www.cnblogs.com/abclife/p/12731060.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有