一.索引简介

众所周知,索引是关系型数据库中给数据库表中一列或多列的值排序后的存储结构,SQL的主流索引结构有B+树以及Hash结构,聚集索引以及非聚集索引用的是B+树索引。这篇文章会总结SQL Server以及MySQL的InnoDB和MyISAM两种SQL的索引。

SQL Sever索引类型有:唯一索引,主键索引,聚集索引,非聚集索引。

MySQL 索引类型有:唯一索引,主键(聚集)索引,非聚集索引,全文索引。

二.聚集索引

聚集(clustered)索引,也叫聚簇索引。

定义:数据行的物理顺序与列值(一般是主键的那一列)的逻辑顺序相同,一个表中只能拥有一个聚集索引。

单单从定义来看是不是显得有点抽象,打个比方,一个表就像是我们以前用的新华字典,聚集索引就像是拼音目录,而每个字存放的页码就是我们的数据物理地址,我们如果要查询一个“哇”字,我们只需要查询“哇”字对应在新华字典拼音目录对应的页码,就可以查询到对应的“哇”字所在的位置,而拼音目录对应的A-Z的字顺序,和新华字典实际存储的字的顺序A-Z也是一样的,如果我们中文新出了一个字,拼音开头第一个是B,那么他插入的时候也要按照拼音目录顺序插入到A字的后面,现在用一个简单的示意图来大概说明一下在数据库中的样子:

地址

id

username

score

0x01

1

小明

90

0x02

2

小红

80

0x03

3

小华

92

..

..

..

..

0xff

256

小英

70

注:第一列的地址表示该行数据在磁盘中的物理地址,后面三列才是我们SQL里面用的表里的列,其中id是主键,建立了聚集索引。

结合上面的表格就可以理解这句话了吧:数据行的物理顺序与列值的顺序相同,如果我们查询id比较靠后的数据,那么这行数据的地址在磁盘中的物理地址也会比较靠后。而且由于物理排列方式与聚集索引的顺序相同,所以也就只能建立一个聚集索引了。

聚集索引实际存放的示意图

从上图可以看出聚集索引的好处了,索引的叶子节点就是对应的数据节点(MySQL的MyISAM除外,此存储引擎的聚集索引和非聚集索引只多了个唯一约束,其他没什么区别),可以直接获取到对应的全部列的数据,而非聚集索引在索引没有覆盖到对应的列的时候需要进行二次查询,后面会详细讲。因此在查询方面,聚集索引的速度往往会更占优势。

创建聚集索引

如果不创建索引,系统会自动创建一个隐含列作为表的聚集索引。

1.创建表的时候指定主键(注意:SQL Sever默认主键为聚集索引,也可以指定为非聚集索引,而MySQL里主键就是聚集索引)

create table t1(

id int primary key,

name nvarchar(255)

)

2.创建表后添加聚集索引

SQL Server

create clustered index clustered_index on table_name(colum_name)

MySQL

alter table table_name add primary key(colum_name)

值得注意的是,最好还是在创建表的时候添加聚集索引,由于聚集索引的物理顺序上的特殊性,因此如果再在上面创建索引的时候会根据索引列的排序移动全部数据行上面的顺序,会非常地耗费时间以及性能。

三.非聚集索引

非聚集(unclustered)索引。

定义:该索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同,一个表中可以拥有多个非聚集索引。

其实按照定义,除了聚集索引以外的索引都是非聚集索引,只是人们想细分一下非聚集索引,分成普通索引,唯一索引,全文索引。如果非要把非聚集索引类比成现实生活中的东西,那么非聚集索引就像新华字典的偏旁字典,他结构顺序与实际存放顺序不一定一致。

非聚集索引实际存放的示意图

非聚集索引的二次查询问题

非聚集索引叶节点仍然是索引节点,只是有一个指针指向对应的数据块,此如果使用非聚集索引查询,而查询列中包含了其他该索引没有覆盖的列,那么他还要进行第二次的查询,查询节点上对应的数据行的数据。

如有以下表t1:

id

username

score

1

小明

90

2

小红

80

3

小华

92

..

..

..

256

小英

70

以及聚集索引clustered index(id), 非聚集索引index(username)。

使用以下语句进行查询,不需要进行二次查询,直接就可以从非聚集索引的节点里面就可以获取到查询列的数据。

select id, username from t1 where username = '小明'

select username from t1 where username = '小明'

但是使用以下语句进行查询,就需要二次的查询去获取原数据行的score:

select username, score from t1 where username = '小明'

在SQL Server里面查询效率如下所示,Index Seek就是索引所花费的时间,Key Lookup就是二次查询所花费的时间。可以看的出二次查询所花费的查询开销占比很大,达到50%。

在SQL Server里面会对查询自动优化,选择适合的索引,因此如果在数据量不大的情况下,SQL Server很有可能不会使用非聚集索引进行查询,而是使用聚集索引进行查询,即便需要扫描整个聚集索引,效率也比使用非聚集索引效率要高。

本人试过在含有30w行表上建立非聚集索引,查询非聚集索引覆盖以外的列就会变成聚集索引的全索引扫描(index scan)查询来避免二次查询,而在另外一张200w行表才会用到非聚集索引seek对应的列再进行kek lookup,有关于SQL Server的有Index seek,index scan, table scan,key LookUp这几个概念,可以查看这个blog,描写比较详细。

但在MySQL里面就算表里数据量少且查询了非键列,也不会使用聚集索引去全索引扫描,但如果强制使用聚集索引去查询,性能反而比非聚集索引查询要差,这就是两种SQL的不同之处。

还有一点要注意的是非聚集索引其实叶子节点除了会存储索引覆盖列的数据,也会存放聚集索引所覆盖的列数据。

如何解决非聚集索引的二次查询问题

复合索引(覆盖索引)

建立两列以上的索引,即可查询复合索引里的列的数据而不需要进行回表二次查询,如index(col1, col2),执行下面的语句

select col1, col2 from t1 where col1 = '213';

要注意使用复合索引需要满足最左侧索引的原则,也就是查询的时候如果where条件里面没有最左边的一到多列,索引就不会起作用。

在SQL Server中还有include的用法,可以把非聚集索引里包含的列包含进来,而不一定需要建立复合索引。

四.总结与使用心得

使用聚集索引的查询效率要比非聚集索引的效率要高,但是如果需要频繁去改变聚集索引的值,写入性能并不高,因为需要移动对应数据的物理位置。

非聚集索引在查询的时候可以的话就避免二次查询,这样性能会大幅提升。

不是所有的表都适合建立索引,只有数据量大表才适合建立索引,且建立在选择性高的列上面性能会更好。

另附本人博客地址

mysql聚集索引和非聚集索引的区别_聚集索引与非聚集索引的总结相关推荐

  1. mysql幻读和不可重复读的区别_面试官:MySQL的可重复读级别能解决幻读吗

    Java面试笔试面经.Java技术每天学习一点 Java面试 关注不迷路 作者:宁愿. 来源:https://juejin.im/post/5c9040e95188252d92095a9e 引言 之前 ...

  2. java非阻塞 串口读数据_串口阻塞与非阻塞

    VTIME定义要求等待的时间量(取值不能大于cc_t). VMIN定义了要求等待的最小字节数. options.c_cc[VTIME] = X; //设置从获取到1个字节后开始计时的超时时间(单位为分 ...

  3. 深入浅出的mysql第三版和第二版的区别_读《深入浅出Mysql》第二版,笔记

    买了本书,同时网上找了电子版 (My)SQL入门 DDL(Data Definition Languages) ||DESCRIBE tablename; DML(Data manipulation ...

  4. 即时系统和非即时系统的区别?_企业即时通讯系统拥有哪些二次开发能力?

    一.企业即时通讯常见的二次开发能力 日常工作中,沟通如空气般必不可少,因此即时通讯软件是常驻在企业桌面的应用,在操作系统右侧状态栏中的托盘图标闪动能即时的提醒用户有新的消息等待阅读. 随着办公需求的多 ...

  5. 动态内存的申请和非动态内存的申请_深圳罗湖“限制非深户申请公办学位”惹争议,官方权威回应来了...

    每年的学位申请 对家长来说就像一场比赛 要操心的事情实在太多了!  比如:今年我家孩子会不会无学可上? 而昨天一则通告则是将在罗湖的家长们急坏了 ▼ 昨日(1月7日),深圳罗湖区教育局发布<罗湖 ...

  6. 微分算法 非侵入式负荷识别_基于决策树的非侵入式负荷识别技术

    基于决策树的非侵入式负荷识别技术 杨雨 ; [期刊名称] <科学技术创新> [年 ( 卷 ), 期] 2018(000)013 [摘要] 本文旨在对非侵入式电力负荷监测与分解技术进行研究 ...

  7. 非标自动化转行机器人_一个4年非标自动化行业成长感触与同行分享

    12年我从模具行业直接转到自动化行业,做一名机械设计师,我进入的公司也是新转型公司,之前是做模具的,后来看到医疗自动化行业前景比较好也就转型了. 转行后我的基本工资是5000/月;主要任务是做自动化设 ...

  8. 钢化膜全覆盖非全覆盖的区别_钢化膜和水凝膜的区别

    一.钢化膜 1.钢化膜就是使用钢化玻璃制作的手机膜,主要分为全覆盖和非全覆盖两类.顾名思义,全覆盖是指能覆盖包括屏幕显示部分和边框的钢化膜,而非全覆盖钢化膜通常只能覆盖屏幕显示部分和上下部分边框. 2 ...

  9. 即时系统和非即时系统的区别?_家庭装修,能不能让热水来得快一点——即时热水系统...

    即时热水 很多小伙伴都应该体验过冬天用冷水刷牙洗脸,如果想用热水就需要放掉很多冷水,等热水来.在一般情况中,打开龙头就有热水,是别墅.大平层等高档装修,甚至豪华装修的专有. 从打开龙头,到手伸到龙头下 ...

  10. 钢化膜全覆盖非全覆盖的区别_什么是3D全覆盖钢化膜,为什么大家都在用?

    原标题:什么是3D全覆盖钢化膜,为什么大家都在用? 同手机屏幕一样,手机钢化玻璃膜也经历了2D到2.5D到3D的发展.3D只是一个营销噱头吗?对不起,并不是. 下面一张图告诉你三者之间的区别:2D不用 ...

最新文章

  1. java用函数读取json_Java解析(读取)Json
  2. python opencv卡尺测量边缘距离
  3. SAP限定同名程序同时运行数量
  4. Spring Boot参数校验以及分组校验的使用
  5. (常用API)正则表达式匹配练习
  6. configure: error: Cannot find php-config. Please use --with-php-config=PATH
  7. 【WiFi密码破解详细图文教程】ZOL仅此一份 详细介绍从CDlinux U盘启动到设置扫描破解
  8. 前端学习(3156):react-hello-react之脚手架文件_src
  9. 从 class 文件 看 synchronize 锁膨胀过程(偏向锁 轻量级锁 自旋锁 重量级锁)
  10. NiFi导出自己模板和导入别人模板
  11. 讨论记录:求大于一个时间段的最大平均积分,O(n)时间实现
  12. ASP.Net下绑定TextBox回车事件的解决方法
  13. 大数据如何学习 cda认证_大数据学习之学习要求
  14. 常用传感器讲解四--水位传感器(water sensor)
  15. 解析小觅中通过双目相机生成深度图的代码
  16. 手机html页面图片不显示,是什么原因?HTML插入图片显示不出来?
  17. 偏序集、偏序关系和格
  18. Android系统驱动介绍
  19. 图片基本处理(imageView2)
  20. python——通信原理,进程与线程

热门文章

  1. Chrome主页被劫持
  2. 书到用时方恨少,收集并不断积累资源【不断更新】
  3. 串管理——鸟友们快来看啊——看清楚点_悟sphenic_新浪博客
  4. crm软件助力企业实现销售自动化
  5. 计算机怎么搜索程序和文件格式,「闪电搜索」一款电脑必备的搜索文件软件,还有Everything...
  6. 计算机科学与技术导论小报,电子科大信息论导论复习精要.doc
  7. CISP学习资料整理归纳
  8. 进入系统后长时间无反应症状【丶Demond CSDN博客】
  9. 基于ArkUI框架开发——图片模糊处理的实现
  10. 呼吸灯——verilog 实现