广告
返回顶部
首页 > 资讯 > 数据库 >SQL-索引
  • 527
分享到

SQL-索引

SQL-索引 2018-10-08 19:10:19 527人浏览 绘本
摘要

理解“聚集索引”和“非聚集索引” ① 聚集索引(clustered   index,也称聚类索引、簇集索引):把内容本身就是一种按照一定规则排列的目录称为“聚集索引”        我们的汉语字典的正文本身就是一个聚集索引。比如,我们要查

SQL-索引

理解“聚集索引”和“非聚集索引”

聚集索引(clustered   index,也称聚类索引、簇集索引):把内容本身就是一种按照一定规则排列的目录称为“聚集索引”

       我们的汉语字典的正文本身就是一个聚集索引。比如,我们要查“安”字,就会很自然地翻开字典的前几页,因为“安”的拼音是“an”,而按照拼音排序汉字的字典是以英文字母“a”开头并以“z”结尾的,那么“安”字就自然地排在字典的前部。如果您翻完了所有以“a”开头的部分仍然找不到这个字,那么就说明您的字典中没有这个字;同样的,如果查“张”字,那您也会将您的字典翻到最后部分,因为“张”的拼音是“zhang”。也就是说,字典的正文部分本身就是一个目录,您不需要再去查其他目录来找到您需要找的内容。

② 非聚集索引(nonclustered   index,也称非聚类索引、非簇集索引):目录纯粹是目录,正文纯粹是正文的排序方式称为“非聚集索引”

       如果您认识某个字,您可以快速地从自动中查到这个字。但您也可能会遇到您不认识的字,不知道它的发音,这时候,您就不能按照刚才的方法找到您要查的字,而需要去根据“偏旁部首”查到您要找的字,然后根据这个字后的页码直接翻到某页来找到您要找的字。但您结合“部首目录”和“检字表”而查到的字的排序并不是真正的正文的排序方法,比如您查“张”字,我们可以看到在查部首之后的检字表中“张”的页码是672页,检字表中“张”的上面是“驰”字,但页码却是63页,“张”的下面是“弩”字,页面是390页。很显然,这些字并不是真正的分别位于“张”字的上下方,现在您看到的连续的“驰、张、弩”三字实际上就是他们在非聚集索引中的排序,是字典正文中的字在非聚集索引中的映射。我们可以通过这种方式来找到您所需要的字,但它需要两个过程,先找到目录中的结果,然后再翻到您所需要的页码。

由以上解释,就很容易理解:每个表只能有一个聚集索引,因为目录只能按照一种方法进行排序。

 

索引使用的误区

主键就是聚集索引

        通常,我们会在每个表中都建立一个 ID 列,以区分每条数据,并且这个 ID 列是自动增大的,步长一般为 1 。这种 ID 是自动生成,我们并不知道每条记录的ID号,所以我们很难在实践中用 ID 号来进行查询( 若要查询需要提前知道要查询记录的 ID 号,这就有点本末倒置了 )。

② 只要建立索引就能显著提高查询速度

        并非是在任何字段上简单地建立索引就能提高查询速度,因此建立“适当”的聚合索引对于我们提高查询速度是非常重要的

③ 把所有需要提高查询速度的字段都加进聚集索引,以提高查询速度

        仅用聚集索引的起始列作为查询条件和同时用到复合聚集索引的全部列的查询速度是几乎一样的,甚至比用上全部的复合索引列还要略快(在查询结果集数目一样的情况下);而如果仅用复合聚集索引的非起始列作为查询条件的话,这个索引是不起任何作用的。

 

索引使用经验总结

① 用聚合索引比用不是聚合索引的主键速度快

用聚合索引比用一般的主键作order   by时速度快,特别是在小数据量情况下

        如果数据量很小的话,用聚集索引作为排序列要比使用非聚集索引速度快得明显的多;而数据量如果很大的话,如10万以上,则二者的速度差别不明显。

使用聚合索引内的时间段,搜索时间会按数据占整个数据表的百分比成比例减少,而无论聚合索引使用了多少个

④ 日期列不会因为有分秒的输入而减慢查询速度

 建立一个“适当”的索引体系,特别是对聚合索引的创建

        引有助于提高检索性能,但过多或不当的索引也会导致系统低效。因为用户在表中每加进一个索引,数据库就要做更多的工作。过多的索引甚至会导致索引碎片。

 

不良的sql

   不良的 SQL 往往来自于 不恰当的索引设计不充份的连接条件 和 不可优化的 where 子句 。在对它们进行适当的优化后,其运行速度有了明显地提高!

① 不恰当的索引设计

缺省情况下建立的索引是非聚集索引,但有时它并不是最佳的;合理的索引设计要建立在对各种查询的分析和预测上。一般来说:

• 有大量重复值、且经常有范围查询( between , > , < , >= , <= )和 order by 、group by 发生的列,可考虑建立聚集索引;

• 经常同时存取多列,且每列都含有重复值可考虑建立组合索引; 

• 组合索引要尽量使关键查询形成索引覆盖,其前导列一定是使用最频繁的列。

 不充份的连接条件

eg:表 card 有 7896行,在 card_no 上有一个非聚集索引,表 account 有 191122行,在 account_no 上有一个非聚集索引。试看在不同的表连接条件下,两个 SQL 的执行情况:

1 select sum(a.amount) from account a,card b where a.card_no = b.card_no(20秒)
2 -- 将SQL改为:
3 select sum(a.amount) from account a,card b where a.card_no = b.card_no and a.account_no=b.account_no(< 1秒)
4 -- 在第一个连接条件下,最佳查询方案是将 account 作外层表,card 作内层表,利用 card 上的索引,其 I/O 次数可由以下公式估算为: 5 ---- 外层表 account 上的 22541页 +( 外层表 account 的 191122行 * 内层表 card 上对应外层表第一行所要查找的3页 )= 595907 次 I/O

6 -- 在第二个连接条件下,最佳查询方案是将 card 作外层表,account 作内层表,利用 account 上的索引,其 I/O 次数可由以下公式估算为: 7 ---- 外层表 card 上的 1944页 +( 外层表 card 的 7896行 * 内层表 account 上对应外层表每一行所要查找的4页 )= 33528 次 I/O

可见,只有充份的连接条件,真正的最佳方案才会被执行。

        多表操作在被实际执行前,查询优化器会根据连接条件,列出几组可能的连接方案并从中找出系统开销最小的最佳方案。连接条件要充份考虑带有索引的表、行数多的表。

       内外表的选择可由公式:外层表中的匹配行数 * 内层表中每一次查找的次数确定,乘积最小为最佳方案。

 不可优化的 where 子句

        # where子句中对列的任何操作结果都是在SQL运行时逐列计算得到的,因此它不得不进行表搜索,而没有使用该列上面的索引;如果这些结果在查询编译时就能得到,那么就可以被SQL优化器优化,使用索引,避免表搜索。

eg:

 1 select * from record where substring ( card_no , 1 , 4) ="5378"(13秒)
 2 --改为下面的SQL
 3 select * from record where card_no like "5378%"<1秒 )
 4 
 5 select * from record where amount/30 < 1000 ( 11秒 )
 6 --改为下面的SQL
 7 select * from record where amount < 1000*30<1秒)
 8 
 9 select * from record where convert ( char(10) , date , 112 ) = "19991201"(10秒)
10 --改为下面的SQL
11 select * from record where date= "1999/12/01"< 1秒)

# 所谓优化即where子句利用了索引,不可优化即发生了表扫描或额外开销

eg:表 stuff 有 200000 行,id_no 上有非聚集索引,请看下面这个 SQL :

select count(*) from stuff where id_no in("0","1") (23秒)

       where条件中的 "in" 在逻辑上相当于 "or" ,所以语法分析器会将 in ( "0" , "1" ) 转化为 id_no = "0" or id_no = "1" 来执行。

  我们期望它会根据每个 or 子句分别查找,再将结果相加,这样可以利用 id_no 上的索引;但实际上( 根据 showplan ),它却采用了 " OR 策略 " ,即先取出满足每个 or 子句的行,存入临时数据库的工作表中,再建立唯一索引以去掉重复行,最后从这个临时表中计算结果。因此,实际过程没有利用 id_no 上索引,并且完成时间还要受 tempdb 数据库性能的影响。

▶ 实践证明,表的行数越多,工作表的性能就越差,当 stuff 有 620000行 时,执行时间竟达到 220秒 !还不如将 or 子句分开:

select count(*) from stuff where id_no="0"
select count(*) from stuff where id_no="1"

得到两个结果,再作一次加法合算。因为每句都使用了索引,执行时间只有3秒,在 620000行 下,时间也只有 4秒。

▶ 用更好的方法,写一个简单的存储过程:

 1 create proc count_stuff as
 2 declare @a int
 3 declare @b int
 4 declare @c int
 5 declare @d char(10)
 6 begin
 7 select @a=count(*) from stuff where id_no="0"
 8 select @b=count(*) from stuff where id_no="1"
 9 end
10 select @c=@a+@b
11 select @d=convert(char(10),@c)
12 print @d

直接算出结果,执行时间同上面一样快!

由以上三点,可以总结以下结论

 

任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边。

 

in 、or 子句常会使用工作表,使索引失效;如果不产生大量重复值,可以考虑把子句拆开;拆开的子句中应该包含索引。

 

要善于使用存储过程,它使 SQL 变得更加灵活和高效。

 

---- 从以上这些例子可以看出,SQL 优化的实质就是在结果正确的前提下,用优化器可以识别的语句,充份利用索引,减少表扫描的 I/O 次数,尽量避免表搜索的发生。

 

 

FILLFACTOR ( 填充因子 )

要理解填充因子的作用,首先需要理解什么是页拆分

页拆分

        在创建聚集索引时,表中的数据按照索引列中的值的顺序存储在数据库的数据页中。在表中插入新的数据行或更改索引列中的值时,SQL Server 必须重新组织表中的数据存储,以便为新行腾出空间,保持数据的有序存储。这同样适用于非聚集索引。添加或更改数据时,SQL Server 不得不重新组织非聚集索引页中的数据存储。向一个已满的索引页添加某个新行时,SQL Server 把大约一半的行移到新页中以便为新行腾出空间。这种重组称为页拆分。

        页拆分会降低性能并使表中的数据存储产生碎片。

填充因子的作用理解

       当创建一个新索引,或重建一个存在的索引时,你可以指定一个填充因子,它是在索引创建时索引里的数据页被填充的数量。

       填充因子设置为 100 意味着每个索引页 100% 填满,50% 意味着每个索引页 50% 填满。 如果你创建一个填充因子为 100 的聚集索引( 在一个非单调递增的列上 ),那意味着每当一个记录被插入( 或修改 )时,页拆分都会发生,因为在现存的页上没有这些数据的空间。

       eg:假定你刚刚用缺省的填充因子新创建了一个索引。当sqlserver创建它时,它把索引放在相邻的物理页面上,因为数据能够顺序的读所以这样会有最优的i/o访问。但当表随着、、增加和改变时,发生了页拆分。当页拆分发生时,sqlserver必须在磁盘的某处分配一个新的页,这些新的页和最初的物理页不是连续的。因此,访问使用的是随机的i/o,而不是有顺序的i/o,这样访问索引页会变得更慢。

填充因子如何设置比较好

原则:

低更改的表(读写比率为100:1):100%的填充因子

高更改的表(写超过读)50-70%的填充因子

读写各一半的:80-90%的填充因子 

您可能感兴趣的文档:

--结束END--

本文标题: SQL-索引

本文链接: https://www.lsjlt.com/news/8737.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • SQL索引(索引优化)
    #1.最左前缀匹配原则,非常重要的原则, create index ix_name_email on s1(name,email,) - 最左前缀匹配:必须按照从左到右的顺序匹配 select * from s1 wher ...
    99+
    2021-11-01
    SQL索引(索引优化)
  • SQL索引
    SQL索引 遥远的将不再遥远,平凡的已不再平凡。 索引 index 索引是一种排好序的快速查找的数据结构,它帮助数据库高效的进行数据的检索。在数据之外,数据库系统还维护着满足特定查找算法的数据结构(额外的存储空间),这些数据结构以某种...
    99+
    2016-08-19
    SQL索引
  • SQL-索引
    理解“聚集索引”和“非聚集索引” ① 聚集索引(clustered   index,也称聚类索引、簇集索引):把内容本身就是一种按照一定规则排列的目录称为“聚集索引”        我们的汉语字典的正文本身就是一个聚集索引。比如,我们要查...
    99+
    2018-10-08
    SQL-索引
  • 【SQL SERVER】索引
    在做开发过程中经常会接触数据库索引,不只是DBA才需要知道索引知识,了解索引可以让我们写出更高质量代码。简单介绍索引的概述,聚集索引,非聚集索引,唯一索引,复合索引,筛选索引使用及注意事项 在做开发过...
    99+
    2019-05-21
    【SQL SERVER】索引
  • SQL之索引
    创建一张表:    QString querystr;     querystr="create tabl...
    99+
    2022-10-18
  • sql 索引问题-where字段索引
    假如有一个表TableTest,已为CREATE_TIME字段设置索引,取值如'2017-11-12 21:52:49'。那么(1)sql写法:DATE_FORMAT(CREATE_TIME,'%Y-%m-...
    99+
    2022-10-18
  • SQL之SQL索引怎么建立
    SQL索引是用于提高查询效率的一种数据结构。通过建立索引,可以让数据库快速定位到存储在表中的数据。下面是建立SQL索引的一些常见方法...
    99+
    2023-09-14
    SQL
  • SQL Server索引维护的sql语句
    这篇文章主要介绍“SQL Server索引维护的sql语句”,在日常操作中,相信很多人在SQL Server索引维护的sql语句问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”...
    99+
    2022-10-18
  • sql索引优化思路
    【开发】SQL优化思路(以oracle为例) powered by wanglifeng https://www.cnblogs.com/wanglifeng717 单表查询的优化思路 单表查询是最简单也是最重要的模块,它是多表等查询的...
    99+
    2020-02-17
    sql索引优化思路
  • SQL中索引怎么用
    小编给大家分享一下SQL中索引怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧! 1、概念&nb...
    99+
    2022-10-19
  • SQL Server 全文搜索/全文索引
    全文引擎使用全文索引中的信息来编译可快速搜索表中的特定词或词组的全文查询。全文索引将有关重要的词及其位置的信息存储在数据库表的一列或多列中。全文索引是一种特殊类型的基于标记的功能性索引,它是由 SQL Server 全文引...
    99+
    2014-12-30
    SQL Server 全文搜索/全文索引
  • 【SQL应知应会】索引(三)• MySQL版:聚簇索引与非聚簇索引;查看索引与删除索引;索引方法
    欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享,与更多的人进行学习交流 本文收录于SQL应知应会专栏,本专栏主要用于记录对于数据库的一些学习,有基础也有进阶,有MySQL也有Oracle 索引 • MySQL...
    99+
    2023-08-24
    sql mysql 数据库 oracle 大数据 面试
  • SQL Server 2014的重建索引
    对于表的index来说,如果这个表的index size非常大的话,建议对这个表的index单独重建索引。 对全表做重建索引: alter index all on Table rebuild w...
    99+
    2022-10-18
  • SQL索引的优化方法
    这篇文章主要讲解了“SQL索引的优化方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SQL索引的优化方法”吧!SELECT TOP 50ROW_N...
    99+
    2022-10-18
  • 怎么用SQL建立索引
    这篇文章主要讲解了“怎么用SQL建立索引”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么用SQL建立索引”吧!用SQL建立索引为了给一个表建立索引,启动任...
    99+
    2022-10-18
  • SQL Server索引有什么用
    这篇文章给大家分享的是有关SQL Server索引有什么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。索引的概念索引的用途:我们对数据查询及处理速度已成为衡量应用系统成败的标准...
    99+
    2022-10-18
  • mysql添加索引的方法(Navicat可视化加索引和sql语句加索引)
    使用索引的场景: 阿里云日志里出现了慢sql  然后发现publish_works_id字段会经常用于一些关联,所以决定把这个字段加上索引,优化sql 可视化navicat操作字段加索引,选择字段所在的表,第一步:右键->设计表 第二步:...
    99+
    2023-09-22
    mysql 数据库 sql
  • sql中怎么实现聚集索引和非聚集索引
    这期内容当中小编将会给大家带来有关sql中怎么实现聚集索引和非聚集索引,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。聚集索引   一种索引,该索引中键值的逻辑顺序决定了表...
    99+
    2022-10-18
  • mysql添加索引方法详解(Navicat可视化加索引与sql语句加索引)
    目录使用索引的场景:下面是通过sql语句添加索引的方法:1、普通索引1)、直接创建索引2)、修改表结构的方式添加索引3)、删除索引2、唯一索引1)、创建唯一索引2)、修改表结构3、主键索引4、组合索引5、全文索引1)、创...
    99+
    2022-11-15
  • Oracle 建立索引及SQL优化
    数据库索引: 索引有单列索引复合索引之说 如何某表的某个字段有主键约束和唯一性约束,则Oracle 则会自动在相应的约束列上建议唯一索引。数据库索引主要进行提高访问速度。 建设原则:  1、索引应该经常建在Where ...
    99+
    2015-01-04
    Oracle 建立索引及SQL优化
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作