首页 > 数据库 >数据库索引的使用

数据库索引的使用

时间:2024-07-30 09:52:17浏览次数:10  
标签:语句 数据库 使用 查询 索引 SQL 失效

对SQL语句进行性能分析

对SQL语句进行性能分析的目的是对性能较差的语句进行优化。

第一,SQL执行频率。我们需要弄清楚哪类语句性能较差、执行频次更高。主要优化的是查询select语句,如果表主要执行的语句是插入语句,实际上是没有必要对索引进行优化的。MySQL的客户端可以通过show [session|global] status命令查看当前数据库中不同增删改查语句的执行频次。

第二,慢查询日志。通过查询不同类型语句的执行频次,不能知道哪些select语句需要进行优化。慢查询日志记录了索引执行时间超过指定时间的索引SQL语句。MySQL的慢查询日志默认不开启,需要手动在配置文件中进行配置和设置参数。

第三,查看profile详情。慢查询日志无法记录一些其他需要优化的语句,可以使用show profiles命令,查看SQL语句的耗时情况。首先,我们需要查看have_profiling参数查看是否支持该功能,然后需要手工配置来开启该功能。show profiles命令可以显示各条语句的执行时间开销,找到其中需要优化的语句之后,可以使用show profile命令查看指定query_id的语句各个阶段的时间延迟(如优化、执行等阶段)。

第四,explain查看执行计划。在select语句前面加上explain关键字可以获取DBMS如何执行语句的各种信息,包括表如何连接、连接的顺序、使用的索引等等信息。

explain语句的输出包含多个字段,有不同的含义。:

  • id。表示查询中执行的子句或操作表的顺序,顺序为,值越大越先执行,相等时从上往下执行。

  • select_type。只是说明查询类型,常见的取值有SIMPLE(不使用连接或子查询的简单查询)、PRIMARY(主查询,外层查询)、SUBQUERY(子查询)等等。

  • type。表示连接类型,会反映性能优劣,由好到差依次为NULL、system、const、eq_ref、ref、range、index、all,显然我们应该尽量向前优化。NULL通常是语句不访问任何表,system是访问系统表,const是使用主键或唯一索引访问,ref是使用非唯一性的索引访问,index表示使用了索引但是仍遍历整个索引,all则表示全表扫描。

  • possible_key。可能使用的索引,可能有一个或多个。

  • key。实际执行使用的索引,如果没有使用任何索引,则为NULL。

  • key_len。使用的索引的字节数。

  • rows。MySQL认为需要执行查询的行数,并不总是准确的。

  • filtered。返回查询结果的行数占总共读取行数的百分比,显然是越大越好。

  • extra。额外的信息。

索引的使用

最左前缀原则

最左前缀原则是使用多列索引(联合索引)时需要遵循的一个原则,指的是查询从索引的最左列开始,且不跳过索引中的任何一列,如果跳过了某一列,索引将部分失效,也就是后面的字段上的索引会失效。

除此之外还有一个关于范围查询的原则:在联合索引中,如果出现范围查询(>号或<号),范围查询右侧的列索引会失效。要想规避这种情况,可以使用大于等于或小于等于符号,前提是需求允许的情况下。

索引何时失效

什么是索引失效?是指DBMS无法有效地利用已有的索引来加速查询的情况。索引失效时,查询操作的性能通常会下降。

  1. 不要在索引列上进行(函数)运算操作,否则索引会失效。

  2. 字符串类型的字段没加引号,索引会失效。(因为类型问题)

  3. 字符串模糊查询时,如果进行头部模糊匹配,索引会失效,但是如果只进行尾部模糊匹配,索引不会失效。

  4. 使用or连接的查询条件,只有两侧的字段都有索引时,索引才会生效。

  5. 如果DBMS评估使用索引比全表扫描还要慢,则不会使用索引。

使用SQL提示索引的使用

使用SQL提示是优化的一个重要手段,通过在SQL语句中人为加入提示来优化操作。使用SQL提示来优化索引的使用,有三种操作:提示使用某个索引;忽略某个索引;强制使用某个索引。

覆盖索引与回表查询

覆盖索引指的是,查询使用了索引,并且查询结果中需要返回的字段,在该索引中已经能够全部找到。因此,我们应该尽量使用覆盖索引。

如果没有使用覆盖索引,则查询在使用了索引之后,仍然需要回表查询数据,性能会降低。

上图中,第一个查询语句可以直接通过聚集索引得到结果,第二个查询语句需要使用name字段上的二级索引得到结果,第三个语句由于需要查询的字段中存在一个不再索引中,因此需要进行回表查询。

前缀索引

当字段类型为字符串(比如varchar、text等)时,有时需要索引很长的字符串,这会导致索引变得很大,查询时,会浪费大量磁盘IO,影响效率。要解决这个问题,可以只将字符串的一部分前缀建立索引,可以大大节约索引空间,从而提高索引效率。

建立前缀索引时,需要指定前缀长度。最好的前缀长度可以根据索引的选择性来决定,选择性是指不重复的索引值数目和表的记录总数比值,索引选择性数值越高(唯一索引的选择性为1,性能最好)则查询效率越高。

单列索引与联合索引

在业务场景中,如果存在多个查询条件,建议建立联合索引,而非单列索引。

索引的设计原则

  1. 针对于数据量较大, 且查询比较频繁的表建立索引。

  2. 针对于常作为查询条件 (where)、排序(order by)、分组(group by)操作的字段建立索引。

  3. 尽量选择区分度高的列作为索引, 尽量建立唯-索引,区分度越高,使用索引的效率越高。

  4. 如果是字符串类型的字段, 字段的长度较长,可以针对于字段的特点,建立前缀索引。

  5. 尽量使用联合索引, 减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间,避免回表,提高查询效率。

  6. 要控制索引的数量, 索引并不是多多益善,索引越多,维护索引结构的代价也就越大,会影响增删改的效率。

  7. 如果索引列不能存储NULL值, 应该在创建表时使用NOT NULL约東它。当优化器知道每列是香包含NULL值时,它可以更好地确定哪个索引最有效地用于查询。

标签:语句,数据库,使用,查询,索引,SQL,失效
From: https://www.cnblogs.com/louistang0524/p/18331595

相关文章

  • Docker中Docker网络-理解Docker0与自定义网络的使用示例
    场景CentOS7中Docker的安装与配置:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/119028701在上面安装好Docker之后。关于对Docker中默认docker0以及自定义网络的使用进行学习。注:博客:https://blog.csdn.net/badao_liumang_qizhi实现理解docker0docker是......
  • 使用OpenCV实时检测不同形状的交通标志
    我正在尝试创建一个可以从摄像头检测交通标志的应用程序。然而,我在检测标志时遇到了一些困难。由于交通标志的颜色可能不同,所以我希望先检测标志的形状。我尝试先找到所有轮廓并尝试检测每个轮廓的形状。然而,标志的轮廓不够清晰,树木背景包含大量小轮廓,会影响检测。这样程......
  • 如何使用我的 CoreML 模型在 Vision 中获取 MLMultiArray 输出
    我正在尝试在swift中将我的CoreMl模型与Vision框架结合使用。我的模型输出一个MLMultiArray。当我通过Vision运行它时,我确实得到了一个输出,但是输出的类型是VNObservation,我无法使用它,也无法将其转换为MLMultiArray。有谁知道如何获取MLMultiArray作为输出,或将VNOb......
  • 传统的cdn技术如何与pcdn技术结合使用
    传统的cdn技术如何与pcdn技术结合使用传统的CDN技术与PCDN技术可以结合使用,以形成互补协作的关系,提供更加高效和优质的内容分发服务。这种结合使用可以通过以下方式实现:1.协同工作:传统的CDN技术主要依赖于中心化的服务器进行内容分发,而PCDN技术则利用用户设备之间的P2P连......
  • 经常使用的第三方类库总结
    1.概述在项目开发过程中,一般我们都会用到很多类库,比如spring,guava,hutool,apacheio/commons等等等等相关一堆类库。本文就来介绍一下常见的类库以及使用方式,以作备忘和学习。1.1为什么学习类库?1.1.1提高效率这是使用类库最重要的原因!使用别人写好的类库可以很大程......
  • 只讲干货!!数据库的裤腰带!!今天拿下:MySQL中的约束!!
    MySQL中的约束约束概述        数据库约束是对表中的数据进行进一步的限制,保证数据的正确性、有效性和完整性主键约束(PrimaryKey)PK        主键约束是使用最频繁的约束。在设计数据表时,一般情况下,都会要求表中设置一个主键。        ......
  • TorchVision 对整个模型与主干模型使用预训练权重
    TorchVision检测模型有一个weights和一个weights_backbone参数。使用预训练weights是否意味着模型在幕后使用了预训练weights_backbone?我正在训练RetinaNet模型,我不确定应该使用这两个选项中的哪一个以及它们之间有什么区别。这正是......
  • 局部变量,在使用时再定义
    关于局部变量,适时定义可以提高代码可读性并规避不必要的bug。示例代码中,为了避免误解`checkTaskApplyDTO`仅设置了`userId`,在`existAppliedTask`方法内部,可以通过将`checkTaskApplyDTO`的定义与设置属性的操作靠近,以明确其所有属性值的来源。另外,本文还展示了一个因提前定义变量`r......
  • 使用 init 和 Fore 时 Colorama 未按预期工作
    我已经安装了colorama库并用python3.12编写它。然后,我尝试使用colorama但它没有按预期工作。当然,首先我导入了init和Fore。然后我输入了init()。之后我写了print(Fore.RED+"someredtext")。它给出了这个随机的单词和字母字符串。[31msome红色文本阅......
  • 使用chainlit快速构建类似OPEN AI一样的对话网页
    快速开始创建一个文件,例如“chainlit_chat”mkdirchainlit_chat进入chainlit_chat文件夹下,执行命令创建python虚拟环境空间(需要提前安装好pythonsdk。Chainlit需要python>=3.8。,具体操作,由于文章长度问题就不在叙述,自行百度),命令如下:python-mvenv.venv这......