索引实效情况

2024-06-03 17:08
文章标签 索引 情况 实效

本文主要是介绍索引实效情况,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

索引失效&子查询-慢查询的起因

原创   2015年07月11日 22:06:52
  • 2827

目前,Mysql作为常用的数据库,在各类业务中被广泛运用。但是其设计并非是十全十美,一些我们认为“高效“的语句,在执行时会花费大量的时间,导致页面出现超时错误。

这里举一些简单的bad case,希望大家以后处理慢sql时能有所参考。(不想研究分析过程的,请移步总结)


子查询是一个坑

业务中,我们定义了两张表:用户参加项目表(user_project)和用户公会情况表(union_user)。user_project表中有user_id和project_id字段来标记用户参与项目的对应关系,同时这两个字段都为索引。而union_user表中有user_id和union_id字段来标记用户属于哪个公会,这两字段也全为索引。

那么假设我们需要查询一个“某公会的用户参与了哪一些项目“时,自然而然会想到用这样的语句进行查询:

[sql]  view plain  copy
  1. SELECT * FROM user_project   
  2. WHERE user_id in   
  3. (SELECT user_id FROM union_user WHERE union_id=1)  

在我们的想象中,查询应该是这样的:

同时,查询中用到的键都建立了索引,所以应该相当快吧!?

但是事实上,这条语句执行的效率相当之差,执行一次花费的时间在10s以上。那么问题出在哪里呢?

我们使用测试库来分析一下这条语句:


可以发现user_project没有使用user_id这个键进行查询,遍历了表中所有的4条记录。

索引为啥没有起效呢?这里就要介绍两个知识点了:

  • 第一个为Mysql在处理所有的查询的时候都强行转换为联接来执行,将每个查询包括多表中关联匹配,关联子查询,union,甚至单表的的查询都处理为联接,接着Mysql执行联接,把每个联接在处理为一个嵌套循环;
  • 第二个知识点:在Mysql在处理子查询的时候,会将子查询改写,Mysql将会扫描外查询中的所有数据,每条数据都将会传到子查询中进行关联,子查询不能首先被执行,如果外表很大的话,那么性能上将会出现问题。

事实上,我们的查询语句被Mysql转化成如下格式进行执行:

[sql]  view plain  copy
  1. SELECT * FROM `user_project`   
  2. WHERE EXISTS   
  3. (SELECT * FROM union_user   
  4. where union_id=1   
  5. and union_user.user_id=user_project.user_id)   

分析其执行过程,可以发现是不会经过user_id索引的:


如何避免子查询的这一问题呢?直接使用联表查询即可:

[sql]  view plain  copy
  1. SELECT * FROM `user_project`  
  2.  INNER JOIN union_user using (user_id)  
  3.  where union_id=1  

分析该语句,发现有效使用了user_id的索引,查询遍历的行数大大降低。

索引失效的一些case

1.           使用OR

SQL如下:

[sql]  view plain  copy
  1. SELECT * FROM `user_project` where id=1 or user_id=1  

虽然查询所用的字段都是索引,但是最终mysql并没有使用其中任何一个。


2.           like查询是以%开头

SQL如下:

[sql]  view plain  copy
  1. SELECT * FROM `userWHERE `user_name` LIKE 'abc%'  

能够正确使用索引:


SQL修改为:

[sql]  view plain  copy
  1. SELECT * FROM `userWHERE `user_name` LIKE '%abc'  

查询时就会不使用索引


3.           查询字符型不用引号

如果代码使用拼串去写语句,同时根据数据的类型决定是否加上引号,那么会构造出这样的语句:

[sql]  view plain  copy
  1. SELECTFROM `userWHERE user_name=123  

而这样的语句实际上是不走索引的:


所以建议还是使用bind来进行参数传递,预防注入的同时,避免这种坑爹问题。

4.           多列索引不查询前一部分

表中的有一个多列索引status,用到了status和score两个字段:


如果只查询status,那么索引是有效的


但是只查询score这一字段,不去查status,那么这个多列索引并不会起效:

总结

总结一下以上的坑:

  • 尽量使用联表查询来替代子查询,因为使用子查询会使索引失效;
  • 查询条件中谨慎使用or;
  • 多列索引设置时请考虑好使用场景,如果有只查其中部分字段的情况,该索引可能不会生效;
  • 查询字符型时请加上引号,确保使用索引;
  • 以%开头的like查询不会走索引。

这篇关于索引实效情况的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1027596

相关文章

宝塔安装的MySQL无法连接的情况及解决方案

《宝塔安装的MySQL无法连接的情况及解决方案》宝塔面板是一款流行的服务器管理工具,其中集成的MySQL数据库有时会出现连接问题,本文详细介绍两种最常见的MySQL连接错误:“1130-Hostisn... 目录一、错误 1130:Host ‘xxx.xxx.xxx.xxx’ is not allowed

MySQL索引失效问题及解决方案

《MySQL索引失效问题及解决方案》:本文主要介绍MySQL索引失效问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql索引失效一、概要二、常见的导致MpythonySQL索引失效的原因三、如何诊断MySQL索引失效四、如何解决MySQL索引失

C# foreach 循环中获取索引的实现方式

《C#foreach循环中获取索引的实现方式》:本文主要介绍C#foreach循环中获取索引的实现方式,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、手动维护索引变量二、LINQ Select + 元组解构三、扩展方法封装索引四、使用 for 循环替代

MySQL索引的优化之LIKE模糊查询功能实现

《MySQL索引的优化之LIKE模糊查询功能实现》:本文主要介绍MySQL索引的优化之LIKE模糊查询功能实现,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一、前缀匹配优化二、后缀匹配优化三、中间匹配优化四、覆盖索引优化五、减少查询范围六、避免通配符开头七、使用外部搜索引擎八、分

浅析CSS 中z - index属性的作用及在什么情况下会失效

《浅析CSS中z-index属性的作用及在什么情况下会失效》z-index属性用于控制元素的堆叠顺序,值越大,元素越显示在上层,它需要元素具有定位属性(如relative、absolute、fi... 目录1. z-index 属性的作用2. z-index 失效的情况2.1 元素没有定位属性2.2 元素处

查看Oracle数据库中UNDO表空间的使用情况(最新推荐)

《查看Oracle数据库中UNDO表空间的使用情况(最新推荐)》Oracle数据库中查看UNDO表空间使用情况的4种方法:DBA_TABLESPACES和DBA_DATA_FILES提供基本信息,V$... 目录1. 通过 DBjavascriptA_TABLESPACES 和 DBA_DATA_FILES

Mysql中InnoDB与MyISAM索引差异详解(最新整理)

《Mysql中InnoDB与MyISAM索引差异详解(最新整理)》InnoDB和MyISAM在索引实现和特性上有差异,包括聚集索引、非聚集索引、事务支持、并发控制、覆盖索引、主键约束、外键支持和物理存... 目录1. 索引类型与数据存储方式InnoDBMyISAM2. 事务与并发控制InnoDBMyISAM

StarRocks索引详解(最新整理)

《StarRocks索引详解(最新整理)》StarRocks支持多种索引类型,包括主键索引、前缀索引、Bitmap索引和Bloomfilter索引,这些索引类型适用于不同场景,如唯一性约束、减少索引空... 目录1. 主键索引(Primary Key Index)2. 前缀索引(Prefix Index /

Go使用pprof进行CPU,内存和阻塞情况分析

《Go使用pprof进行CPU,内存和阻塞情况分析》Go语言提供了强大的pprof工具,用于分析CPU、内存、Goroutine阻塞等性能问题,帮助开发者优化程序,提高运行效率,下面我们就来深入了解下... 目录1. pprof 介绍2. 快速上手:启用 pprof3. CPU Profiling:分析 C

MySQL进阶之路索引失效的11种情况详析

《MySQL进阶之路索引失效的11种情况详析》:本文主要介绍MySQL查询优化中的11种常见情况,包括索引的使用和优化策略,通过这些策略,开发者可以显著提升查询性能,需要的朋友可以参考下... 目录前言图示1. 使用不等式操作符(!=, <, >)2. 使用 OR 连接多个条件3. 对索引字段进行计算操作4