SQL优化 MySQL版 - 避免索引失效原则(一)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: SQL优化 MySQL版 - 避免索引失效原则(一) 避免索引失效原则(一) 精力有限,剩余的失效原则将会在 《避免索引失效原则(二)》中连载出来,请谅解 作者 : Stanley 罗昊 【转载请注明出处和署名,谢谢!】 避免索引失效的一些原则 我们编写SQL语句后会进行添加一些索引进行优化,但.

SQL优化 MySQL版 - 避免索引失效原则(一)

避免索引失效原则(一)

精力有限,剩余的失效原则将会在 《避免索引失效原则(二)》中连载出来,请谅解

作者 : Stanley 罗昊

转载请注明出处和署名,谢谢!

避免索引失效的一些原则

我们编写SQL语句后会进行添加一些索引进行优化,但是有时候确实建了索引,但索引有时候会失效

比如在模糊查询使用 in 关键字的时候索引就失效了,这只是其中的一个条件;

1.复合索引的时候,不要跨列或无序使用(最佳左前缀)

我在前几篇文章有重点介绍过;

就比如你建立了一个索引 分别字段为 a b c,你使用的时候却没有从a开始向后依次使用,而是使用了a c 把中间的b漏掉了下面我举个例子:

比如我 where a ...  and b ...  order by c,这种使用顺序就符合最佳做前缀,我从左向右依次使用了索引,如果你写成下面这样:

where b ... and a order by c,这样很明显你顺序不对,并不满足最佳左前缀,从而导致了索引失效

2.复合索引,尽量使用全索引匹配

假设我现在建立了一个复合索引 a b c,在查询的时候,尽量把这些索引字段都用上;

比如我现在想找一个张三,你先根据 a 找,再根据b找,最后再根据c找,这样找就会更快一点,尽量不要你建了三个索引你却只用两个,这样虽然可以,但是却把一级目录给删了;

就跟看书一样,我要找书上一个精确内容,准确来说先看目录,再看章节,再看最后的小结,道理是一样的;

3.不要在索引上进行任何操作

如果你在索引上进行任何操作,索引就必将失效,什么是任何操作,下发我将举例说明:

比如你对索引进行加减乘除计算,进行一些函数计算,或进行一些类型转换,在这种情况下,索引都会失效;

比如我select ... where A.x = ...;简单写一个这样的就行了,不要再进行一些花里胡哨的操作,这里假设A.x是索引

你不要写成:select... where A.x*3 = ....;即是是索引,你算完之后就失效了,就不要这样干!

这里就给大家演示一下:我现在编写一条SQL语句记得前面加explain:

select * from book where authroid = 1 and typeid = 2;

首先book表中的 authroid 跟 typeid 均是索引:

通过key_len可以清楚的发现我用到了两个索引一个是四,两个加起来就是八,这两个索引本别是authroid  typeid ,而且查询效率是ref级别,接下来我就对它进行一些操作;

explain select * from book where authroid = 1 and typeid*2 = 2;

执行结果:

虽然我们的查询级别仍然是ref,但是值得注意的是,key_len变成了四,我明明写了两个索引,现在却少了一个,明明有两个索引,你却用了一个,原因很简单,因为我在typeid上进行乘法操作了!

如果还不能明白,我这次把这两个索引字段都进行操作

explain select * from book where authroid*2 = 1 and typeid*2 = 2;

执行结果:

这个结果够明显了把,查询级别变成了ALL,而且我明明有两个索引,却一个都没有用!所以从这里面就能得出结论,不能对索引进行任何操作,否则就会导致索引失效!

4.对于复合索引左边失效右边全部失效

现在我们对上一条SQL语句再进行更改操作:

select * from book where authroid*2 = 1 and typeid = 2;

这条SQL语句authroid typeid 这两个字段是复合索引,我现在给authroid字段进行操作,下面我们看执行结果:

我即便没有对typid进行任何操作,但是导致的结果却是全部失效

原因很简单,在复合索引下,你左前第一个失效,那么你后面全部跟着失效;

假设有 a b c 这些字段是复合索引,我给a 字段进行乘法操作,那么b c 字段都将会失效;

给b加字段,b后面的全部字段都会失效,a不受影响

这里值得一提的是,如果有两个复合索引,比如 a1 a2是一个复合索引,b1 b2也是一个复合索引,即便a1在左边a1失效了a2会跟着失效但是b1 b2不受影响,因为复合索引与复合索引之间是没有任何关系的;

5.复合索引不能使用不等于(!= 或 <> is null (is not null))

如果用以上其中一种,会导致资深以及右侧索引全部失效,下面我将会举例说明:

我现在编写一条SQL语句j记得前面加上explain 

select * from book where authoid = 1 and typeid = 2

其中authoid typeid 均是复合索引:

执行结果发现一些异常现象,首先key里面只生效了一个,在key_len里面是4不是8,因为我用了两个索引应该是8才对我也没有对索引进行操作,但就是失效了一个;

原因:SQL优化是一种概率层面的优化,至于是否实际使用了我们的优化,需要通过explaini进行推测,在possible_keys中我们可以看到,它预测使用了两个索引,但实际它就是只用了一个,因为MySQL优化是概率的,即便你手动优化的很少,有时你照样正常生效,这正常现象,因为手动优化试只是概率;

现在我们不管概率问题,我们继续紧接着上刚才的例子;

我们看到authroid仍在生效,我们这次把authroid进行一些不等于操作

explain  select * from book where authoid ! = 1 and typeid = 2

执行结果:

奇怪的事情又发生了,这次查询级别仍是fef但是我们发现authoid确实失效了但是typeid生效了

原来authoid失效只是你自身失效了,并不影响其他字段的生效概率,也可以理解为typeid把authoid给干掉了!

那么接下来我都给他加上不等于试试:

explain  select * from book where authoid ! = 1 and typeid ! = 2;

执行结果:

这里我就不再过多阐述了,很显然,全部失效了

今日感悟:

年轻人:“我有很多好的想法”

智者:“想和做,是两种接人不同的境界,不要把自己“想做”一件事情误会成自己“在做”一件事情”

智者:“另外,不要把“在做”一件事,误会成“做成”一件事”

作者:罗昊 感谢各位阅读学习, 如果有疑问或纠错请在评论区留言与我交流,再次感谢各位读者的支持
相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
19天前
|
缓存 算法 关系型数据库
MySQL底层概述—8.JOIN排序索引优化
本文主要介绍了MySQL中几种关键的优化技术和概念,包括Join算法原理、IN和EXISTS函数的使用场景、索引排序与额外排序(Using filesort)的区别及优化方法、以及单表和多表查询的索引优化策略。
MySQL底层概述—8.JOIN排序索引优化
|
19天前
|
SQL 关系型数据库 MySQL
MySQL底层概述—7.优化原则及慢查询
本文主要介绍了:Explain概述、Explain详解、索引优化数据准备、索引优化原则详解、慢查询设置与测试、慢查询SQL优化思路
MySQL底层概述—7.优化原则及慢查询
|
20天前
|
存储 缓存 关系型数据库
MySQL底层概述—5.InnoDB参数优化
本文介绍了MySQL数据库中与内存、日志和IO线程相关的参数优化,旨在提升数据库性能。主要内容包括: 1. 内存相关参数优化:缓冲池内存大小配置、配置多个Buffer Pool实例、Chunk大小配置、InnoDB缓存性能评估、Page管理相关参数、Change Buffer相关参数优化。 2. 日志相关参数优化:日志缓冲区配置、日志文件参数优化。 3. IO线程相关参数优化: 查询缓存参数、脏页刷盘参数、LRU链表参数、脏页刷盘相关参数。
MySQL底层概述—5.InnoDB参数优化
|
4天前
|
SQL 存储 缓存
MySQL的架构与SQL语句执行过程
MySQL架构分为Server层和存储引擎层,具有高度灵活性和可扩展性。Server层包括连接器、查询缓存(MySQL 8.0已移除)、分析器、优化器和执行器,负责处理SQL语句;存储引擎层负责数据的存储和读取,常见引擎有InnoDB、MyISAM和Memory。SQL执行过程涉及连接、解析、优化、执行和结果返回等步骤,本文详细讲解了一条SQL语句的完整执行过程。
15 3
|
11天前
|
监控 关系型数据库 MySQL
MySQL和SQLSugar百万条数据查询分页优化
在面对百万条数据的查询时,优化MySQL和SQLSugar的分页性能是非常重要的。通过合理使用索引、调整查询语句、使用缓存以及采用高效的分页策略,可以显著提高查询效率。本文介绍的技巧和方法,可以为开发人员在数据处理和查询优化中提供有效的指导,提升系统的性能和用户体验。掌握这些技巧后,您可以在处理海量数据时更加游刃有余。
41 9
|
5天前
|
SQL 关系型数据库 MySQL
基于SQL Server / MySQL进行百万条数据过滤优化方案
对百万级别数据进行高效过滤查询,需要综合使用索引、查询优化、表分区、统计信息和视图等技术手段。通过合理的数据库设计和查询优化,可以显著提升查询性能,确保系统的高效稳定运行。
17 2
|
4天前
|
SQL 关系型数据库 OLAP
云原生数据仓库AnalyticDB PostgreSQL同一个SQL可以实现向量索引、全文索引GIN、普通索引BTREE混合查询,简化业务实现逻辑、提升查询性能
本文档介绍了如何在AnalyticDB for PostgreSQL中创建表、向量索引及混合检索的实现步骤。主要内容包括:创建`articles`表并设置向量存储格式,创建ANN向量索引,为表增加`username`和`time`列,建立BTREE索引和GIN全文检索索引,并展示了查询结果。参考文档提供了详细的SQL语句和配置说明。
24 1
|
9天前
|
关系型数据库 MySQL
图解MySQL【日志】——磁盘 I/O 次数过高时优化的办法
当 MySQL 磁盘 I/O 次数过高时,可通过调整参数优化。控制刷盘时机以降低频率:组提交参数 `binlog_group_commit_sync_delay` 和 `binlog_group_commit_sync_no_delay_count` 调整等待时间和事务数量;`sync_binlog=N` 设置 write 和 fsync 频率,`innodb_flush_log_at_trx_commit=2` 使提交时只写入 Redo Log 文件,由 OS 择机持久化,但两者在 OS 崩溃时有丢失数据风险。
23 3
|
11天前
|
SQL Oracle 关系型数据库
【YashanDB 知识库】如何将 mysql 含有 group by 的 SQL 转换成崖山支持的 SQL
在崖山数据库中执行某些 SQL 语句时出现报错(YAS-04316 not a single-group group function),而这些语句在 MySQL 中能成功执行。原因是崖山遵循 SQL-92 标准,不允许选择列表中包含未在 GROUP BY 子句中指定的非聚合列,而 MySQL 默认允许这种操作。解决办法包括:使用聚合函数处理非聚合列或拆分查询为两层,先进行 GROUP BY 再排序。总结来说,SQL-92 更严格,确保数据一致性,MySQL 在 5.7 及以上版本也默认遵循此标准。
|
22天前
|
SQL 关系型数据库 MySQL
MySQL原理简介—11.优化案例介绍
本文介绍了四个SQL性能优化案例,涵盖不同场景下的问题分析与解决方案: 1. 禁止或改写SQL避免自动半连接优化。 2. 指定索引避免按聚簇索引全表扫描大表。 3. 按聚簇索引扫描小表减少回表次数。 4. 避免产生长事务长时间执行。

热门文章

最新文章