Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 1000|回复: 0

开发交流:数据库索引白话篇

[复制链接]

该用户从未签到

发表于 2011-10-24 10:01:32 | 显示全部楼层 |阅读模式
数据库索引白话篇
    “索引”这个名字,想必大家都耳熟能详了,众所周知,索引最大的用途就是提升数据库的查询速度。或许,你会说,我曾经自己动手按书上讲的方法试验了一番,可是没有感觉有多大速度的提升呢?这完全是可能的,因为索引就像是一门非常厉害的武功招式,如果我们想发挥其最大的功力,光凭招式的纯熟是远远不够的,我们还必须同时修炼其高深的内功方可……
    就上面的问题,首先,我们一般的学习和试验情境中,很难会遇到大数据量的情况,什么叫大数据量?10000条算不算大?10万、100万呢……
    就个人目前经历的情况来看,一般只有上了10万这个级别,才能初现索引的优势,这也就是说,当我们通过小数据量数据库进行实际操作的时候,可能只有通过使用函数的方法,才能在毫秒级别上得到一个比较满意的结果,但如果想从实际应用角度获取“真实”的索引效果,大数据量是一个必须的前提。
    学习讲究从0开始,我们就从索引的“招式”讲起……
    首先,请大家回忆一下,我们在使用汉语词典查找一个汉字的时候,通常可以怎么做?
对了,我们一般有两种方法:首先,对于我们认识的字,我们可以直接通过其拼音的首字母进行初步定位,然后再通过后面的拼音进行逐次定位,最终找到汉字,如“索”字,我们首先通过其拼音“suo”可以知道,我们必须首先找到s,然后再翻找u,最后找到o,这时,我们再翻一两页一般就能找到我们要找的汉字了;但如果我们遇到一个不认识的字,又该咋办呢?例如“引”这个汉字,我们可以通过笔画数或者偏旁部首进行查找,即通过将笔画数相同的所有汉字或者偏旁都一样的所有汉字进行集中,并在其后附加上该字的具体页码,这样,当我们逐个汉字进行查找时,一旦找到这个汉字,我们就能马上定位其所在的页码,可谓相当精确!
    我们终于在字典中找到了“索引”这两个汉字,先让我们稍微庆祝一下,因为我们已经基本掌握了索引的原理了!你不信?好,让我们细细谈来……
    无论是通过拼音直接查询,还是通过笔画,抑或是偏旁查询,我们都是通过实现将这些汉字通过某一种规则进行编排,然后,才能让我们顺利、快速地找到我们要找的汉字,那你有没有想过有这么一本字典,它包含很多的汉字,但是汉字的前后顺序没有任何规则。如果硬要你从这个字典中查到“索”这个汉字,你会怎么做?撞大运,随机进行抽取?虽然也是个办法,但毕竟你能在有限次数内,恰翻到准确页码的几率万分渺茫!最笨且最有效的方法就是从字典的第一页逐页进行查找,直到找到那个汉字为止!如果你要找的汉字恰巧在首页,你真是人品大爆发了,但如果你要找的汉字恰巧在最后一页呢……
    下面让我们把索引和查字典关联起来进行理解,那么得到如下的对应关系:
    字典                            索引
    拼音查找                            聚集索引
    笔画或偏旁查找                      非聚集索引
    最好记着这个对应关系,一旦你对索引的概念有一点迷糊的时候,就翻起手边的字典查两个字,绝对有效!这就是武功招式的秘籍!
    索引共分为两招,第一招为聚集索引,第二招为非聚集索引。
聚集索引的排列顺序和磁盘上物理数据存储的顺序是一致的,它拥有最快的查询速度,且限定每一个数据表只能有一个聚集索引,这很显然,因为物理数据只能有一种排序规则,对应到字典上,按拼音进行编排即为聚集索引,而字典的数据内容即可理解为物理数据。
所谓非聚集索引,即其只将设定的属性列,按照设定的顺序进行排列后的结果数据保存到数据表中,我们可以将其理解成字典中的笔画或偏旁查询页,其中只保存有选定列的内容和其在磁盘中的物理地址,当我们找到所要找的数据时,也就意味着我们已经找到了它的物理存储地址!相比聚集索引来说,它是一种非常精确的查找方式。但是,有一点需要说明,因为非聚集索引需要一定的物理空间来保存排序后的结果集,所以,选择内容短小,经常用于查询的列一方面提高了查询速度,再者也不会对数据库的容量有过多的影响。
很简单吧,索引就是这么简单!既然我们已经把索引的招数熟记于心了,是时候提升我们内功了。所谓内功即我们在何时,对那些属性列建立何种索引?
在SQL Server中,数据库会自动为数据表的主键列建立聚集索引:我们通常情况下,会为一个数据表建一个ID属性列,用于唯一标识数据行内容,这样做可以让我们在查看数据的时候获得方便,但对于数据库的查询性能可没有啥帮助,让我们回想下字典的原理吧,如果一个拼音就是一个页码的话,我要想查找一个拼音的时候,只能退守到最原始的从头至尾查找方式!所以,默认的并不一定是最佳的,我们一定要理解这个概念。
下面就我们日常遇到的一些情况进行总结,并说明使用何种索引更能有效提升性能(只是一般情况,但仍需要具体问题具体分析!):
动作描述使用聚集索引使用非聚集索引
列经常被分组排序应应
返回某范围内的数据应不应
一个或极少不同值不应不应
小数目的不同值应不应
大数目的不同值不应应
频繁更新的列不应应
外键列应应
主键列应应
频繁修改索引列不应应

尤其要注意其中的“小数目不同值”和“大数目不同值”,这往往需要我们的经验来进行区别,没有一个具体的衡量标准。
索引虽然有诸多好处,但过多地建立索引有的时候可能会获得相反的结果,例如可能导致数据库容量过于臃肿、导致数据库正常的INSERT,UPDATE和DELETE等操作的性能大大降低等,这就要求我们必须要多结合实际的情况进行分析,以建立最优的索引。
当然,如何编写SQL语句也是影响索引性能的一个重要方面,下面有几点需要特别留意:
1.   日期属性列,不会因为有分秒差别而减慢查询速度
2.   使用LIKE比较进行查询时,如果模式以特定字符串如“abc%”开头,使用索引则会提高效率;如果模式以通配符如“%xyz”开头,则索引不起作用
3.   OR会引起全表扫描,且和IN的作用相当,但建立索引仍旧会有比较明显的效果提升~
4.   尽量少用NOT
5.   EXISTS 和 IN的执行效率是一样的
6.   用函数charindex()和前面加通配符%的LIKE执行效率一样
7.   UNION并不绝对比OR的执行效率高
8.   字段提取要按照“需多少、提多少”的原则,避免“SELECT *”
9.   COUNT(*)不比COUNT (字段)慢
10. ORDER BY按聚集索引列排序效率最高
11. 多用“TOP”进行数据提取,可提高效率
索引的优缺点比较:
索引的优点
1.创建唯一性索引,保证数据库表中每一行数据的唯一性
2.大大加快数据的检索速度,这也是创建索引的最主要的原因
3.加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
4.在使用分组和排序子句进行数据检索时,同样可以显着减少查询中分组和排序的时间。
5.通过使用索引,可以在查询的过程中使用优化隐藏器,提高系统的性能。
索引的缺点
1.创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加
2.索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大
3.当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度
最后还是那句话,大家一定要活学多用,才能逐渐领悟索引的内功的奥妙,虽然索引的用法多变,但使用的原则不变,那就是“简单才是王道!”祝大家学习顺利!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

GMT+8, 2025-1-11 01:36 , Processed in 0.295946 second(s), 36 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表