首页 > 数据库 >SQL---索引

SQL---索引

时间:2024-03-05 16:22:51浏览次数:27  
标签:数据 聚集 --- 索引 SQL 失效 where 主键

今天我们一起学习并梳理一下数据库中的索引的知识,带着以下几个问题,去深入的了解。

what:索引是什么?索引有哪几种类型?
why: 为什么要用到索引?作用是什么?优点和缺点?
who: 谁去使用?开发人员或测试人员
where: 在代码中或者sql查询中
when: 开发阶段、测试阶段、性能优化阶段
how: 怎么用的,创建索引,删除索引,索引失效

一、索引是什么?

索引是一种用于快速查询和检索数据的数据结构。 索引的作用就相当于目录的作用。打个比方: 我们在查字典的时候,如果没有目录,那我们就只能一页一页的去找我们需要查的那个字,速度很慢。如果有目录了,我们只需要先去目录里查找字的位置,然后直接翻到那一页就行了。

二、为什么要使用索引?

为了提高查询的效率。
索引一经建立,就由数据库管理系统自动使用和维护,不需要用户干预。建立索引是为了加快数据的查询效率。

2.1索引的优点

①可以大大加快 数据的检索速度(大大减少的检索的数据量), 这也是创建索引的最主要的原因。毕竟大部分系统的读请求总是大于写请求的。
②另外,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。

2.2索引的缺点

①创建索引和维护索引需要耗费许多时间:当对表中的数据进行增删改的时候,如果数据有索引,那么索引也需要动态的修改,会降低 SQL 执行效率。
②占用物理存储空间 :索引需要使用物理文件存储,也会耗费一定空间。

三、索引类型

3.1主键索引

①数据表的主键列使用的就是主键索引

②一张数据表有只能有一个主键,并且主键不能为 null,不能重复

③在 mysql 的 InnoDB 的表中,当没有显示的指定表的主键时,InnoDB 会自动先检查表中是否有唯一索引的字段,如果有,则选择该字段为默认的主键,否则 InnoDB 将会自动创建一个 6Byte 的自增主键

3.2二级索引

二级索引又称为辅助索引,是因为二级索引的叶子节点存储的数据是主键。也就是说,通过二级索引,可以定位主键的位置。

唯一索引,普通索引,前缀索引等索引 均属于二级索引

唯一索引(Unique Key) :唯一索引也是一种约束。唯一索引的属性列不能出现重复的数据,但是允许数据为 NULL,一张表允许创建多个唯一索引。 建立唯一索引的目的大部分时候都是为了该属性列的数据的唯一性,而不是为了查询效率。

普通索引(Index) :普通索引的唯一作用就是为了快速查询数据,一张表允许创建多个普通索引,并允许数据重复和 NULL。

前缀索引(Prefix) :前缀索引只适用于字符串类型的数据。前缀索引是对文本的前几个字符创建索引,相比普通索引建立的数据更小,因为只取前几个字符。

3.3聚集索引

聚集索引:指索引项的排序方式和表中数据记录排序方式一致的索引。它会根据聚集索引键的顺序来存储表中的数据,即对表的数据按索引键的顺序进行排序,然后重新存储到磁盘上。因为数据在物理存放只能有一种排列方式,所以一个表只能有一个聚集索引。比如字典中,用拼音查汉字,就是聚集索引。因为正文中字都是按照拼音排序的。而用偏旁部首查汉字,就是非聚集索引,因为正文中的字并不是按照偏旁部首排序的,我们通过检字表得到正文中的字在索引中的映射,然后通过映射找到所需要的字。

聚集索引并不是一种单独的索引类型,而是一种数据存储方式。将数据存储于索引放到了一块,索引结构的叶子节点保存了行数据。另外,主键索引属于聚集索引。

优点

聚集索引的查询速度非常的快,因为整个 B+树本身就是一颗多叉平衡树,叶子节点也都是有序的,定位到索引的节点,就相当于定位到了数据。

缺点

①依赖于有序的数据 :因为 B+树是多路平衡树,如果索引的数据不是有序的,那么就需要在插入时排序,如果数据是整型还好,否则类似于字符串或 UUID 这种又长又难比较的数据,插入或查找的速度肯定比较慢。
②更新代价大 : 如果对索引列的数据被修改时,那么对应的索引也将会被修改,而且况聚集索引的叶子节点还存放着数据,修改代价肯定是较大的,所以对于主键索引来说,主键一般都是不可被修改的。

3.4非聚集索引

非聚集索引:与聚集索引相反,索引顺序与物理存储顺序不一致。通俗点说:非聚集索引即索引结构和数据分开存放的索引。二级索引属于非聚集索引

优点

更新代价比聚集索引要小 。非聚集索引的更新代价就没有聚集索引那么大了,非聚集索引的叶子节点是不存放数据的。

缺点

非聚集索引也依赖于有序的数据。可能会二次查询(回表) :这应该是非聚集索引最大的缺点了。 当查到索引对应的指针或主键后,可能还需要根据指针或主键再到数据文件或表中查询。

四、索引用法

4.1创建索引

CREATE UNION/CLUSTERED/NONCLUSTERED INDEX 索引名 ON 表名 (列名)

4.2删除索引

DROP INDEX 表名.索引名

4.3怎样查看一条SQL使用了索引?

 没有创建索引,查询时如下:

 给loc字段添加索引,创建索引之后:

4.4索引失效的几种情况

失效的第1种情况
select * from emp where ename like '%T';

ename上即使添加了索引,也不会走索引,为什么?
原因是因为模糊匹配当中以“%”开头了,mysql找不到。
解决方案:尽量避免模糊查询的时候以“%”开始。这是一种优化的手段/策略。

失效的第2种情况:
使用or的时候会失效,如果使用or那么要求or两边的条件字段都要有索引,才会走索引,如果or其中一边有一个字段没有索引,那么另一个字段上的索引也会失效。
解决方案:
不建议使用or,所以这就是为什么不建议使用or的原因。
或使用union联合查询。
举例:
dept表,loc字段有索引,deptname字段没有索引
select * from dept where loc = '福建' or deptname = '信息部';
--- 查询位于福建的或者信息部的部门信息
以上sql语句,由于deptname没有索引,会导致loc的索引失效,可以使用union联合查询:
select * from dept where loc = '福建' union select * from dept where deptname = '信息部';这样loc字段的索引还是生效的。

失效的第3种情况:
使用复合索引的时候,没有用到左侧的字段作为查找条件,索引失效
什么是复合索引?
两个字段,或者更多的字段联合起来添加一个索引,叫做复合索引。
create index emp_job_sal_index on emp(job,sal);

索引正常:explain select * from emp where job = 'MANAGER';
索引失效:explain select * from emp where sal = 800;

失效的第4种情况:
在where当中索引列参加了运算,索引失效。
create index emp_sal_index on emp(sal);

索引正常:explain select * from emp where sal = 800;
索引失效:explain select * from emp where sal+1 = 800;

失效的第5种情况:
在where当中索引列使用了函数

ename字段有索引
explain select * from emp where lower(ename) = 'smith';

 

标签:数据,聚集,---,索引,SQL,失效,where,主键
From: https://www.cnblogs.com/xj-excellent/p/18054249

相关文章

  • python-Grequests,一个好用的 requests库的异步版本!
    Grequests是什么?grequests是一个Python库,它是requests库的异步版本。它允许你同时发送多个HTTP请求,而不必等待每个请求依次响应。可以在等待服务器响应的同时执行其他任务,从而节省时间并提高效率。安装Grequestspipinstallgrequests使用示例一:批量获取网页假如有一个......
  • python-jose,一个好用的 Python 库!
    python-jose介绍:在做接口测试或者接口自动化测试中,身份验证和授权是很重要的一部分。JSONWebToken(JWT)是一种流行的身份验证和授权解决方案,它能够安全地在网络中传输信息。python-jose库是Python中处理JWT的强大工具,提供了丰富的功能和灵活的接口,能够轻松地处理JWT的生成、......
  • Nuxt3 -layout 使用
    Nuxt3-layout使用更多方式查看官网:https://57code.gitee.io/nuxt3-docs-zh/directory-structure/layouts.html1、创建default.vue文件,layout->default.vue 2、app.vue文件内添加layout布局 NuxtLayout 3、页面内使用布局两种方式引入:  ......
  • 2024 年春节集训 _ 第二课 - 数据结构优化动态规划
    【例题\(1\)】递增子序列\(\color{white}{link}\)考虑\(dp.\)\(dp[i][j]\)表示以元素\(i\)为结尾,长度为\(k\)的方案数。那么显而易见就有一个转移方程:\[dp[i][j]=\sum_{a[k]<a[i],\k<i}dp[k][j-1]\]先抛去第二维度的\(j\),这是可以做一个关于\(a[i]\)值的大......
  • 在PowerShell中下载文件是一项常见的任务,可以通过多种方法完成。下面我将介绍使用Invo
    在PowerShell中下载文件是一项常见的任务,可以通过多种方法完成。下面我将介绍使用Invoke-WebRequest、New-Object和Start-BitsTransfer命令来下载文件的方法。使用Invoke-WebRequestInvoke-WebRequest是一个非常强大的命令,用于向网页发送HTTP和HTTPS请求。你可以使用它来下载文......
  • 文心一言 VS 讯飞星火 VS chatgpt (208)-- 算法导论15.4 5题
    五、设计一个O($n^2$)时间的算法,求一个n个数的序列的最长单调递增子序列。要写代码的时候,请用go语言。文心一言,抛panic:在Go语言中设计一个O(n^2)时间复杂度的算法来求一个n个数的序列的最长单调递增子序列(LongestIncreasingSubsequence,LIS)可以使用动态规划的方法......
  • 《Document-level Relation Extraction as Semantic Segmentation》论文阅读笔记
    原文代码摘要本文研究的是文档级关系抽取,即从文档中抽取出多个实体之间的关系。现有的方法主要是基于图或基于Transformer的模型,它们只考虑实体自身的信息,而忽略了关系三元组之间的全局信息。为了解决这个问题,本文提出了一种新的方法,它通过预测一个实体级关系矩阵来同时捕获局......
  • MySQL视图创建
    createorreplaceviewv_user_infoasselect'SCYB'as`医保注册编码`,t.hilist_codeas`医保编码`,t.hilist_nameas`医保名称`,t.pinyinas`拼音码`,t.chrgitm_lvas`收费项目等级`,nullas`收......
  • mysql根据父节点递归查询所有子节点
    SELECTt3.*FROM(SELECTt1.*,IF(FIND_IN_SET(parent_id,@pids)>0,@pids:=CONCAT(@pids,',',id),'0')ASischildFROM(SELECTt.id,t.parent_id,t.NAMEFROMt_parentAStORDERBYt.idASC)t1,......
  • thinkphp8扩展think-swoole4.0
    配置文件config/swoole.php<?php//默认\think\swoole\websocket\Handler::class,usethink\swoole\websocket\socketio\Handler;return['http'=>['enable'=>true,//开启'host'=>......