你能说出SQL聚集索引和非聚集索引的区别吗?
最近突然想起前一阵和一朋友的聊天,当时他问我的问题是一个非常普通的问题:说说SQL聚集索引和非聚集索引的区别。
其实对于非专业的数据库操作人员来讲,例如软件开发人员,在很大程度上都搞不清楚数据库索引的一些基本知识,有些是知其一不知其二,或者是知其然不知其所以然。造成这种情况的主要原因我觉的是行业原因,有很多公司都有自己的DBA团队,他们会帮助你优化SQL,开发人员即使不懂优化问题也不大,所以开发人员对这方面也就不会下太多功夫去了解SQL优化,但如果公司没有这样的DBA呢,就只能靠程序员自己了。 最近突然想起前一阵和一朋友的聊天,当时他问我的问题是一个非常普通的问题:说说SQL聚集索引和非聚集索引的区别。
大家可能认为这个问题难度不大,认为太熟悉了,也许不会感兴趣,但你真能说清楚吗?其实要想说明白这两者的差别也不是三两句就说的清的,那天我也是觉的这问题太泛了,就随便说了其中的两个区别:
- 聚集索引一个表只能有一个,而非聚集索引一个表可以存在多个,这个跟没问题没差别,一般人都知道。
- 聚集索引存储记录是物理上连续存在,而非聚集索引是逻辑上的连续,物理存储并不连续,这个大家也都知道。
上面的两点从大的方面讲都是讲的通的,后面我们继续探讨,举一个实际点的例子,一个学生表student,里面是学生号id,学生姓名,学生所在城市ID,学生成绩(总分)。
问:如果想按姓名查询,如何做优化?
答:在姓名字段上建立索引。
问:建立什么类型的索引?
答:建立非聚集索引。
问:为什么?
答:一般有范围查询的需求,可以考虑在此字段上创建聚集索引。
问:学分有重复性,在学分字段上创建聚集索引能行吗?
....沉思,不能创建吗?之前的项目好像真这样做过,答:应该可以吧。
问:聚集索引的约束是什么?
答:唯一性啊?
问:既然是唯一性,那么学分字段上还能创建聚集索引吗?
....再次沉思,应该可以啊,但索引的约束又怎么说呢?答:应该可以的,以前用过。
我自认为是对数据库索引知识有一定研究的,但可能是有两年没实际接触SQL的原因,一时还真想不出具有说服力的解释,朋友们看到这能解答我的问题吗?
其实上面的我们需要搞清楚以下几个问题:
第一:聚集索引的约束是唯一性,是否要求字段也是唯一的呢?
分析:如果认为是的朋友,可能是受系统默认设置的影响,一般我们指定一个表的主键,如果这个表之前没有聚集索引,同时建立主键时候没有强制指定使用非聚集索引,SQL会默认在此字段上创建一个聚集索引,而主键都是唯一的,所以理所当然的认为创建聚集索引的字段也需要唯一。
结论:聚集索引可以创建在任何一列你想创建的字段上,这是从理论上讲,实际情况并不能随便指定,否则在性能上会是恶梦。
第二:为什么聚集索引可以创建在任何一列上,如果此表没有主键约束,即有可能存在重复行数据呢?
粗一看,这还真是和聚集索引的约束相背,但实际情况真可以创建聚集索引。
分析其原因是:如果未使用 UNIQUE 属性创建聚集索引,数据库引擎将向表自动添加一个四字节 uniqueifier 列。必要时,数据库引擎 将向行自动添加一个 uniqueifier 值,使每个键唯一。此列和列值供内部使用,用户不能查看或访问。
第三:是不是聚集索引就一定要比非聚集索引性能优呢?
如果想查询学分在60-90之间的学生的学分以及姓名,在学分上创建聚集索引是否是最优的呢?
答:否。既然只输出两列,我们可以在学分以及学生姓名上创建联合非聚集索引,此时的索引就形成了覆盖索引,即索引所存储的内容就是最终输出的数据,这种索引在比以学分为聚集索引做查询性能更好。
第四:在数据库中通过什么描述聚集索引与非聚集索引的?
索引是通过二叉树的形式进行描述的,我们可以这样区分聚集与非聚集索引的区别:聚集索引的叶节点就是最终的数据节点,而非聚集索引的叶节仍然是索引节点,但它有一个指向最终数据的指针。
第五:在主键是创建聚集索引的表在数据插入上为什么比主键上创建非聚集索引表速度要慢?
有了上面第四点的认识,我们分析这个问题就有把握了,在有主键的表中插入数据行,由于有主键唯一性的约束,所以需要保证插入的数据没有重复。我们来比较下主键为聚集索引和非聚集索引的查找情况:聚集索引由于索引叶节点就是数据页,所以如果想检查主键的唯一性,需要遍历所有数据节点才行,但非聚集索引不同,由于非聚集索引上已经包含了主键值,所以查找主键唯一性,只需要遍历所有的索引页就行,这比遍历所有数据行减少了不少IO消耗。这就是为什么主键上创建非聚集索引比主键上创建聚集索引在插入数据时要快的真正原因。
好了,讲这这些,不知道大家是否真的了解SQL的聚焦索引,我也是数据库新手(从使用时间上来讲也不算新了,哈哈),不专业,有什么不对的地方,希望大家批评指正,下篇我会分析一些数据库访问索引的情况,有图的情况下,也许看的更加明白。
原文链接:http://www.cnblogs.com/mybluesky99/archive/2011/04/21/2023629.html
你能说出SQL聚集索引和非聚集索引的区别吗?的更多相关文章
- SQL Server-聚焦聚集索引对非聚集索引的影响(四)
前言 在学习SQL 2012基础教程过程中会时不时穿插其他内容来进行讲解,相信看过SQL Server 2012 T-SQL基础教程的童鞋知道前面写的所有内容并非都是摘抄书上内容,如若是这样那将没有任 ...
- SQL Server索引 (原理、存储)聚集索引、非聚集索引、堆 <第一篇>
一.存储结构 在SQL Server中,有许多不同的可用排列规则选项. 二进制:按字符的数字表示形式排序(ASCII码中,用数字32表示空格,用68表示字母"D").因为所有内容都 ...
- SQL Server索引 - 聚集索引、非聚集索引、非聚集唯一索引 <第八篇>
聚集索引.非聚集索引.非聚集唯一索引 我们都知道建立适当的索引能够提高查询速度,优化查询.先说明一下,无论是聚集索引还是非聚集索引都是B树结构. 聚集索引默认与主键相匹配,在设置主键时,SQL Ser ...
- SQL Server 深入解析索引存储(非聚集索引)
标签:SQL SERVER/MSSQL SERVER/数据库/DBA/索引体系结构/非聚集索引 概述 非聚集索引与聚集索引具有相同的 B 树结构,它们之间的显著差别在于以下两点: 基础表的数据行不按非 ...
- SQL Server - 索引详细教程 (聚集索引,非聚集索引)
转载自:https://www.cnblogs.com/hyd1213126/p/5828937.html 作者:爱不绝迹 (一)必读:深入浅出理解索引结构 实际上,您可以把索引理解为一种特殊的目录. ...
- SQL有三个类型的索引,唯一索引 不能有重复,但聚集索引,非聚集索引可以有重复
重要: (1) SQL如果创建时候,不指定类型那么默认是非聚集索引 (2) 聚集索引和非聚集索引都可以有重复记录,唯一索引不能有重复记录. (3) 主键 默认是加了唯一约束的聚集索引,但是也可以在主键 ...
- SQL Server的聚集索引和非聚集索引
微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引.簇集索引)和非聚集索引(nonclustered index,也称非聚类索引.非簇集索引)…… (一) ...
- SQL Server-聚焦聚集索引对非聚集索引的影响
前言 在学习SQL 2012基础教程过程中会时不时穿插其他内容来进行讲解,相信看过SQL Server 2012 T-SQL基础教程的童鞋知道前面写的所有内容并非都是摘抄书上内容,如若是这样那将没 ...
- SQL SERVER 索引之聚集索引和非聚集索引的描述
索引是与表或视图关联的磁盘上结构,可以加快从表或视图中检索行的速度. 索引包含由表或视图中的一列或多列生成的键. 这些键存储在一个结构(B 树)中,使 SQL Server 可以快速有效地查找与键值关 ...
随机推荐
- python基础一 day15 作业
3.处理文件,用户指定要查找的文件和内容,将文件中包含要查找内容的每一行都输出到屏幕def check_file(filename,aim): with open(filename,encoding= ...
- opencv将rgb图像转换成灰度图
python写法: import cv2 img = cv2.imread(img_dir, cv2.IMREAD_GRAYSCALE) cv2.imwrite(dis_dir, img) imrea ...
- Word2vec资料
Word2vec 很好的资料 Word2Vec-知其然知其所以然 https://www.zybuluo.com/Dounm/note/591752 Word2Vec数学原理讲解 http://w ...
- C++ 内存分配操作符new和delete详解
重载new和delete 首先借用C++ Primer 5e的一个例子: string *sp = new string("a value"); ]; 这其实进行了以下三步操作: ...
- sql快速删除所用表,视图,存储过程
[http://www.th7.cn/db/mssql/2011-07-07/10127.shtml#userconsent#] 删除用户表 .select 'DROP TABLE '+name fr ...
- C#数组删除元素
一.C#数组删除元素 在C#中,只能在动态数组ArrayList类中对数组执行删除元素的操作.因为动态数组是一个可以改变数组长度和元素个数的数据类型. 示例: using System;using S ...
- 获取页面的title值
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Oracle 闪回 找回数据的实现方法
Oracle 闪回 找回数据的实现方法 闪回技术是Oracle强大数据库备份恢复机制的一部分,在数据库发生逻辑错误的时候,闪回技术能提供快速且最小损失的恢复.这篇文章主要介绍了Oracle 闪回 找回 ...
- 01_4_Struts路径问题
01_4_Struts路径问题 1. Struts路径问题说明 struts2中的路径问题是根据action的路径而不是jsp路径来确定,所有尽量不要使用相对路径. 虽然可以使用redirect方式解 ...
- 03_2_JAVA中的面向对象与内存解析
03_2_JAVA中的面向对象与内存解析 1. 成员变量 成员变量可以是Java语言中任何一种数据类型(包括基本数据类型和引用数据类型) 在定义成员变量时可以对其初始化,如果不对其初始化,Java使用 ...