Mysql中哪些Sql不走索引

https://blog.csdn.net/qq_32331073/article/details/79041232

                    版权声明:本文为博主原创文章,可以转载不可复制。                        https://blog.csdn.net/qq_32331073/article/details/79041232                    </div>
                                                <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-cd6c485e8b.css">
                                    <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-cd6c485e8b.css">
            <div class="htmledit_views" id="content_views">

要尽量避免这些不走索引的sql:

SELECT `sname` FROM `stu` WHERE `age`+10=30;-- 不会使用索引,因为所有索引列参与了计算 

SELECT sname FROM stu WHERE LEFT(date,4) <1990; 不会使用索引,因为使用了函数运算,原理与上面相同

SELECT * FROM houdunwang WHERE uname LIKE’后盾%’ 走索引

SELECT * FROM houdunwang WHERE uname LIKE “%后盾%” 不走索引

正则表达式不使用索引,这应该很好理解,所以这就是为什么在SQL中很难看到regexp关键字的原因

字符串与数字比较不使用索引;
CREATE TABLE
a (a char(10));
EXPLAIN SELECT
FROM a WHERE a=“1” 走索引
EXPLAIN SELECT
FROM a WHERE a=1 不走索引,同样也是使用了函数运算

select * from dept where dname=‘xxx’ or loc=‘xx’ or deptno=45 –如果条件中有or,即使其中有条件带索引也不会使用。换言之,就是要求使用的所有字段,都必须建立索引,我们建议大家尽量避免使用or 关键字

MySQL内部优化器会对SQL语句进行优化,如果优化器估计使用全表扫描要比使用索引快,则不使用索引

同时,我们需要注意,组合索引遵循 “最左前缀”原则:

组合索引

0、MySQL单列索引和组合索引究竟有何区别呢?

为了形象地对比两者,先建一个表:

CREATE TABLE `myIndex` ( 
  `i_testID` INT NOT NULL AUTO_INCREMENT,  
  `vc_Name` VARCHAR(50) NOT NULL,  
  `vc_City` VARCHAR(50) NOT NULL,  
  `i_Age` INT NOT NULL,  
  `i_SchoolID` INT NOT NULL,  
  PRIMARY KEY (`i_testID`)  
);

假设表内已有1000条数据,在这 10000 条记录里面 7 上 8 下地分布了 5 条 vc_Name=”erquan” 的记录,只不过 city,age,school 的组合各不相同。来看这条 T-SQL:

SELECT `i_testID` FROM `myIndex` WHERE `vc_Name`='erquan' AND `vc_City`='郑州' AND `i_Age`=25; -- 关联搜索;

1、首先考虑建MySQL单列索引:

在 vc_Name 列上建立了索引。执行 T-SQL 时,MYSQL 很快将目标锁定在了 vc_Name=erquan 的 5 条记录上,取出来放到一中间结果集。在这个结果集里,先排除掉 vc_City 不等于”郑州”的记录,再排除 i_Age 不等于 25 的记录,最后筛选出唯一的符合条件的记录。虽然在 vc_Name 上建立了索引,查询时MYSQL不用扫描整张表,效率有所提高,但离我们的要求还有一定的距离。同样的,在 vc_City 和 i_Age 分别建立的MySQL单列索引的效率相似。

2、为了进一步榨取 MySQL 的效率,就要考虑建立组合索引。就是将 vc_Name,vc_City,i_Age 建到一个索引里:

ALTER TABLE `myIndex` ADD INDEX `name_city_age` (vc_Name(10),vc_City,i_Age);

3、建表时,vc_Name 长度为 50,这里为什么用 10 呢?这就是下文要说到的前缀索引,因为一般情况下名字的长度不会超过 10,这样会加速索引查询速度,还会减少索引文件的大小,提高 INSERT 的更新速度。

执行 T-SQL 时,MySQL 无须扫描任何记录就到找到唯一的记录!

4、如果分别在 vc_Name,vc_City,i_Age 上建立单列索引,让该表有 3 个单列索引,查询时和上述的组合索引效率一样吗?答案是大不一样,远远低于我们的组合索引。虽然此时有了三个索引,但 MySQL 只能用到其中的那个它认为似乎是最有效率的单列索引,另外两个是用不到的,也就是说还是一个全表扫描的过程。

5、建立这样的组合索引,其实是相当于分别建立了:

  • vc_Name,vc_City,i_Age
  • vc_Name,vc_City
  • vc_Name

6、这样的三个组合索引!为什么没有 vc_City,i_Age 等这样的组合索引呢?这是因为 mysql 组合索引 “最左前缀” 的结果。简单的理解就是只从最左面的开始组合。并不是只要包含这三列的查询都会用到该组合索引,下面的几个 T-SQL 会用到:

SELECT * FROM myIndex WHREE vc_Name=”erquan AND vc_City=”郑州” 
SELECT * FROM myIndex WHREE vc_Name=”erquan

而下面几个则不会用到:

SELECT * FROM myIndex WHREE i_Age=20 AND vc_City=”郑州” 
SELECT * FROM myIndex WHREE vc_City=”郑州”

也就是,name_city_age(vc_Name(10),vc_City,i_Age) 从左到右进行索引,如果没有左前索引Mysql不执行索引查询。


Note:例如 or 、in | not in 、is null | is not null、!=、<>,使用时并不是完全不走索引,要考虑到:

         1、全表扫描是否比索引更快,以至于优化器选择全表扫描;

         2、mysql-server 的版本。。。;

         3、可以通过优化语法或者配置优化器,走索引。参考:statement-optimization.htmlselect-optimization.htmloptimization-indexes.html

switchable-optimizations.html

         具体问题可见: 为什么where条件中使用or索引不起作用?


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hello_world!

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值