mysql不走索引的几个问题小结
一、类型不匹配导致不走索引
这类问题往往是因为数据定义与使用上面的偏差,比如工号,定义成varchar,然而用的时候又不讲工号打上引号
创建表代码举例如下:
----创建表: CREATE TABLE `test_a`( `id` int(11) NOT NULL, `work_no` varchar(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `index_work_no`(`work_no`) )ENGINE=InnoDB;
查询条件对比如下:
----查询工号,执行一下----- explain SELECT * from test_a where work_no=1000; explain SELECT * from test_a where work_no="1000";
结论,可以自己运行一下代码,会发现上面的因为定义成了varchar,但是用的时候又在把它当int用,没有加引号,导致无法走索引
二、索引用错的问题
这个是索引用错的问题,创建表及初始化数据代码如下:
----创建表: CREATE TABLE `test_t`( `id` int(11) NOT NULL, `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `index_a`(`a`), KEY`index_b`(`b`) )ENGINE=InnoDB; -----定义初始化10w数据函数: delimiter;; create procedure idata() begin declare i int; set i=1; while(i<=100000) do insert into test_t values(i,i,i); set i=i+1; end while; end;; delimiter; call idata(); ----删除存储过程 drop procedure idata;
相关查询对比:
----查询条件 explain select * from test_t where (a BETWEEN 1 and 1000) and (b BETWEEN 50000 and 100000) order by b limit 1; explain select * from test_t force index(index_a) where (a BETWEEN 1 and 1000) and (b BETWEEN 50000 and 100000) order by b limit 1;
结论,最终出现第一个走错了索引,导致查询时候会变长的问题。
而下面的我们加强制走索引,会发现执行扫描行数要少很多,主要原因还是发生在order上
如果做下面的修改不强制走索引也能够走正确的索引就是order by b, a。同时放上去也是有效的
三、条件字段为函数的操作导致不走索引
函数作用在索引字段上导致不走索引,其实感觉mysql尽量少用函数,虽然提供了,往往还是占用的mysql自己的资源做的计算。mysql数据库的资源多贵呀,物理机多便宜呀
----创建表: CREATE TABLE `trade_log`( `id` int(11) NOT NULL, `created_time` datetime NOT NULL DEFAULT, `b` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `index_created_time`(`created_time`) )ENGINE=InnoDB; -----定义初始化10w数据函数: delimiter;; create procedure c_trade_log() begin declare i int; set i=1; while(i<=100000) do insert into trade_log values(i,from_unixtime(1539123415 + 1000*i),i); set i=i+1; end while; end;; delimiter; call c_trade_log(); ----删除存储过程 DROP PROCEDURE c_trade_log
查询条件:
explain SELECT count(*) from trade_log where month(created_time)=7; SELECT count(*) from trade_log where month(created_time)=7; -----优化----- explain SELECT count(*) from trade_log where created_time BETWEEN "2018-07-01" and "2018-08-01" or created_time BETWEEN "2019-07-01" and "2019-08-01" or created_time BETWEEN "2020-07-01" and "2020-08-01" or created_time BETWEEN "2021-07-01" and "2021-08-01" ;
四、错误计算不走索引
查询条件:继续沿用上面的trade_log表
索引字段做减法在等号前,与等号后的区别
--不走索引 explain SELECT * from trade_log where id -1000=3030300 --走索引 explain SELECT * from trade_log where id =3030300-1000
五、in后面的公式
继续使用test_t表
--不走索引 因为有max,不要究竟这儿为什么要加max公式,主要是为了突出这儿不走索引给的一个例子 explain select * FROM test_t WHERE id IN ( SELECT max(id) FROM test_t WHERE a BETWEEN 1000 and 2000 GROUP BY a ) --走索引 explain select * FROM test_t WHERE id IN ( SELECT id FROM test_t WHERE a BETWEEN 1000 and 2000 GROUP BY a )
不走索引的结果:
走索引的结果:
其他:慢sql相关配置开启命令
----慢查询开启情况--- show variables like "slow_query_log"; ----设置开启---- set global slow_query_log = "ON"; ---慢查询日志地址--- show variables like "slow_query_log_file";
到此这篇关于mysql不走索引的几个问题小结的文章就介绍到这了,更多相关mysql不走索引内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
详解记录MySQL中lower_case_table_names的坑
这篇文章主要介绍了详解记录MySQL中lower_case_table_names的坑,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2021-03-03IDEA的database插件无法连接mysql的解决办法(08001错误)
用navicat链接数据库正常,mysql控制台操作正常,但是用IDEA的数据库插件链接一直报 08001 错误,本文就给大家介绍一下IDEA的database插件无法连接mysql报08001错误的解决办法,需要的朋友可以参考下2024-07-07MySQL删除外键时报错Error Code:1091. Can‘t DROP ‘XXX‘的解决方法
这篇文章主要给大家介绍了关于MySQL删除外键时报错Error Code:1091. Can‘t DROP ‘XXX‘的解决方法,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下2022-08-08
最新评论