mysql不走索引的几个问题小结

 更新时间:2023年08月14日 10:49:29   作者:风破冬  
MySQL中不走索引的问题通常发生在查询中使用了函数,这会使索引失效,从而影响查询性能,本文就介绍了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常见问题解决

    mysql常见问题解决

    网上看到了不错的mysql下常见错误解决方法,特整理下,方便大家学习mysql
    2008-02-02
  • mybatis实战之拦截器解读

    mybatis实战之拦截器解读

    这篇文章主要介绍了mybatis实战之拦截器解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Mysql中文乱码问题的最佳解决方法

    Mysql中文乱码问题的最佳解决方法

    这篇文章主要介绍了Mysql中文乱码问题的最佳解决方法,需要的朋友可以参考下
    2014-07-07
  • MySQL错误代码2058和2059的解决办法

    MySQL错误代码2058和2059的解决办法

    这篇文章主要介绍了MySQL错误代码2058和2059的解决办法,2058和2059的错误码核心都是你用的客户端工具和mysql版本的密码插件不匹配,下面就来介绍一下解决方法,感兴趣的可以了解一下
    2025-03-03
  • MySQL如何快速的创建千万级测试数据

    MySQL如何快速的创建千万级测试数据

    这篇文章主要给大家介绍了关于MySQL如何快速的创建千万级测试数据的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用MySQL具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05
  • centos7中如何利用crontab进行mysql定时备份

    centos7中如何利用crontab进行mysql定时备份

    crontab是一个命令,常见于Unix和类Unix的操作系统之中,用于设置周期性被执行的指令,下面这篇文章主要给大家介绍了关于centos7中如何利用crontab进行mysql定时备份的相关资料,需要的朋友可以参考下
    2022-02-02
  • MySQL中的临时表与内存表

    MySQL中的临时表与内存表

    这篇文章主要介绍了MySQL中的临时表与内存表,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • 如何优雅、安全的关闭MySQL进程

    如何优雅、安全的关闭MySQL进程

    这篇文章主要介绍了如何优雅、安全的关闭MySQL进程,帮助大家更好的理解和学习MySQL,感兴趣的朋友可以了解下
    2020-08-08
  • MAC下修改mysql默认字符集为utf8的方法

    MAC下修改mysql默认字符集为utf8的方法

    本文主要介绍了如何修改MAC版mysql默认字符集为utf8,如果你的MAC版mysql字符乱码,可以参考一下这篇文章
    2018-03-03
  • SQL实战演练之网上商城数据库商品类别数据操作

    SQL实战演练之网上商城数据库商品类别数据操作

    一直认为,扎实的SQL功底是一名数据分析师的安身立命之本,甚至可以称得上是所有数据从业者的基本功。当然,这里的SQL绝不单单是写几条查询语句那么简单,接下来请跟着小编通过案例项目演练一遍商品类别的数据操作吧
    2021-10-10

最新评论