SQL Server数据库性能优化之索引篇【转】
http://www.blogjava.net/allen-zhe/archive/2010/07/23/326966.html 性能优化之索引篇
近期项目需要, 做了一段时间的SQL Server性能优化,遇到了一些问题,也积累了一些经验,现总结一下,与君共享。SQL Server性能优化涉及到许多方面,如良好的系统和数据库设计,优质的SQL编写,合适的数据表索引设计,甚至各种硬件因素:网络性能、服务器的性能、 操作系统的性能,甚至网卡、交换机等。这篇文章主要讲到如何改善索引,还将有另一篇讨论如何改善SQL语句。
首先需要强调一下,水能载舟,亦能覆舟。建立“适当”的索引是实现查询优化的首要前提。
当根据索引码的值搜索数据时,索引提供了对数据的快速访问。事实上,没有索引,数据库也能根据SELECT语句成功地检索到结果,但随着表变得越
来越大,使用“适当”的索引的效果就越来越明显。索引有助于提高检索性能,但过多或不当的索引也会导致系统低效。因为用户在表中每加进一个索引,数据库就
要做更多的工作。过多的索引甚至会导致索引碎片。所以,要建立一个“适当”的索引体系,特别是对聚合索引的创建,更应精益求精,以使数据库能得到高性能的
发挥。
简述SQL Server的索引
SQL Server提供了两种索引:聚集索引(clustered index,也称聚类索引、簇集索引)和非聚集索引(nonclustered index,也称非聚类索引、非簇集索引)。
聚集索引确定表中数据的物理顺序。聚集索引类似于电话簿,后者按姓氏排列数据。由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引。但该索引可以包含多个列(组合索引),就像电话簿按姓氏和名字进行组织一样。
聚集索引对于那些经常要搜索范围值的列特别有效。使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻。例如,如果应用
程序执行的一个查询经常检索某一日期范围内的记录,则使用聚集索引可以迅速找到包含开始日期的行,然后检索表中所有相邻的行,直到到达结束日期。这样有助
于提高此类查询的性能。同样,如果对从表中检索的数据进行排序时经常要用到某一列,则可以将该表在该列上聚集(物理排序),避免每次查询该列时都进行排
序,从而节省成本。
非聚集索引与课本中的索引类似。数据存储在一个地方,索引存储在另一个地方,索引带有指针指向数据的存储位置。索引中的项目按索引键值的顺序存
储,而表中的信息按另一种顺序存储(这可以由聚集索引规定)。如果在表中未创建聚集索引,则无法保证这些行具有任何特定的顺序。
更详细的介绍请参考MSDN上关于索引的介绍。http://msdn.microsoft.com/zh-cn/library/ms189271.aspx
使用SQL Server的索引
问题又来了,既然分了两种索引,何时何种情况用何种索引?那就看看下表吧。简单的说就是:对于小数目的不同值,或列经常被分组排序,或需要返回某范围内的数据时使用聚集索引;对于大数目的不同值,或列经常被分组排序,或列被频繁更新时使用非聚集索引。
|
使用聚集索引 |
使用非聚集索引 |
列经常被分组排序 |
应 |
应 |
返回某范围内的数据 |
应 |
不应 |
一个或极少不同值 |
不应 |
不应 |
小数目的不同值 |
应 |
不应 |
大数目的不同值 |
不应 |
应 |
频繁更新的列 |
不应 |
应 |
外键列 |
应 |
应 |
主键列 |
应 |
应 |
频繁修改索引列 |
不应 |
应 |
如何改善索引的一些经验:
1. 索引首先要满足你的应用中最关键或者是被很多用户频繁执行的查询。
若某个查询每月仅执行一次,要考虑是否值得为其涉及表创建了索引。要知道在当月的其它时间数据库系统对该索引的维护开销是要超过满足该查询的表扫描的开销的。所以,好钢用在刀刃上,好索引用在关键频繁的查询上。
2. 在经常进行连接,但是没有指定为外键的列上建立索引。
在嵌套查询中,对表的顺序存取对查询效率可能产生致命的影响。比如采用顺序存取策略,一个嵌套3层的查询,如果每层都查询
1000行,那么这个查询就要查询10亿行数据。避免这种情况的主要方法就是对连接的列进行索引。例如下面的一条SQL,连接这两个表:tblA(id,
c1, c2, …)和tblB(id, …),就需要分别在两个表的id字段上建立索引。
select min(c1) from tblA where c1 > 1 and c2 = 2 -- 会触发Clustered Index Seek。
select min(c1) from tblA where c1 > 1 and c3 < 3 -- 会触发Clustered Index Scan。
select min(c1) from tblA where c2 = 2 and c3 < 3 -- 会触发Clustered Index Scan。
select min(c1) from tblA where c1 > 1 and c2 = 2 and c3 < 3 -- 会触发Clustered Index Seek,且形成了索引覆盖。
其中Clustered Index Scan的执行计划
其中Clustered Index Seek的执行计划
如此可见形成索引覆盖的必要性。
6. 非聚集索引与精确查找的默契
对于某个表中的某个字段存在大数目的不同值时,为该字段建个非聚集索引会达到意想不到的效果。因为数据库系统在搜索数据值时,先对非聚集索引进行
搜索,找到数据值在表中的位置,然后从该位置直接检索数据。因为索引包含描述查询所搜索的数据值在表中的精确位置的条目,这也是为什么非聚集索引是精确匹
配查询的最佳方法。例如,在employee表为emp_id列建了非聚集索引,要搜索其雇员ID (emp_id) >
1000的所有人,SQL Server会在索引中直接跳到emp_id =
1000这样一个条目之后,列出匹配的emp_id列在表中的页和行,然后直接转到该页该行。
7. 如果你是皮尔斯,SQL Server 的执行计划就是朗多
SQL Server 2005的Microsoft SQL Server Management
Studio和Database Engine Tuning
Advisor(DETA)是非常好的性能调试助手,可以使用它们对SQL语句调优,查看估计的执行计划开销,用DETA生成优化建议,采纳或参考索引优
化部分。
需要注意的是,对于估计的执行计划,不要过于关注里面显示的开销比例,而实际上这个有时会误导。我在实际优化过程中就被发现,一个index
scan的执行项开销只占25%,另一个键查找的开销占50%,而键查找部分根本没有可优化的,SEEK谓词就是ID=XXX这个建立在主键上的查找。而
仔细分析可以看到,后者CPU开销0.00015,I/O开销0.0013。而前者呢,CPU开销1.4xxxx,I/O开销也远大于后者。因此,优化重
点应该放在前者。
网上这类的文章很多,这里就不做赘述了。可以参考一篇较早的文章:SQL Server性能调优入门(图文版)
另外还有一篇不错的文章,共享在这里:探讨如何在有着1000万条数据的MS SQL SERVER数据库中实现快速的数据提取和数据分页
SQL Server数据库性能优化之索引篇【转】的更多相关文章
- Sql Server数据库性能优化之索引
最近在做SQL Server数据库性能优化,因此复习下一索引.视图.存储过程等知识点.本篇为索引篇,知识整理来源于互联网. 索引加快检索表中数据的方法,它对数据表中一个或者多个列的值进行结构排序,是数 ...
- SQL Server数据库性能优化之SQL语句篇【转】
SQL Server数据库性能优化之SQL语句篇http://www.blogjava.net/allen-zhe/archive/2010/07/23/326927.html 近期项目需要, 做了一 ...
- SQL Server查询性能优化——覆盖索引(二)
在SQL Server 查询性能优化——覆盖索引(一)中讲了覆盖索引的一些理论. 本文将具体讲一下使用不同索引对查询性能的影响. 下面通过实例,来查看不同的索引结构,如聚集索引.非聚集索引.组合索引等 ...
- SQL Server查询性能优化——创建索引原则(一)
索引是什么?索引是提高查询性能的一个重要工具,索引就是把查询语句所需要的少量数据添加到索引分页中,这样访问数据时只要访问少数索引的分页 就可以.但是索引对于提高查询性能也不是万能的,也不是建立越多的索 ...
- SQL Server 查询性能优化——创建索引原则(一)(转载)
索引是什么?索引是提高查询性能的一个重要工具,索引就是把查询语句所需要的少量数据添加到索引分页中,这样访问数据时只要访问少数索引的分页就可以.但是索引对于提高查询性能也不是万能的,也不是建立越多的索引 ...
- SQL Server 查询性能优化——创建索引原则(一)
索引是什么?索引是提高查询性能的一个重要工具,索引就是把查询语句所需要的少量数据添加到索引分页中,这样访问数据时只要访问少数索引的分页就可以.但是索引对于提高查询性能也不是万能的,也不是建立越多的索引 ...
- SQL Server 查询性能优化——创建索引原则
索引是什么?索引是提高查询性能的一个重要工具,索引就是把查询语句所需要的少量数据添加到索引分页中,这样访问数据时只要访问少数索引的分页就可以.但是索引对于提高查询性能也不是万能的,也不是建立越多的索引 ...
- SQL Server数据库性能优化(二)之 索引优化
参考文献 http://isky000.com/database/mysql-performance-tuning-index 原文作者是做mysql 优化的 但是我觉得 在索引方面 ...
- 转载——SQL Server数据库性能优化之SQL语句篇
转载自:http://www.blogjava.net/allen-zhe/archive/2010/07/23/326927.html 1. 按需索取字段,跟“SELECT *”说拜拜 字段的提取一 ...
随机推荐
- COG注释--转载
http://blog.sina.com.cn/s/blog_670445240102uxwy.html 一 COG简介 COG,即Clusters of Orthologous Groups of ...
- RequireJS 快速入门
说明:本文只提供快速入门内容,方便快速进入实战状态.更高级的配置,请参考官网文档. 当初之所以使用 RequireJS 等工具,是因为想提高js的加载速度,避免不必要的堵塞.但通过一段时间的使用, ...
- Node聊天程序实例05:index.html和style.css
作者:vousiu 出处:http://www.cnblogs.com/vousiu 本实例参考自Mike Cantelon等人的<Node.js in Action>一书. index. ...
- DOM对象与jquery对象有什么不同
jQuery对象和DOM对象使用说明,需要的朋友可以参考下.1.jQuery对象和DOM对象第一次学习jQuery,经常分辨不清哪些是jQuery对象,哪些是 DOM对象,因此需要重点了解jQuery ...
- TinyOS 中的 task
task 的目的 做过界面的编程的同学可能会有这种经历,界面不响应,那,其实程序总是在后台运行,但是后台可能是个for循环,那么界面的点击等事件都不能执行. 在windows界面编程中利用了事件机制来 ...
- centos 7 编译zabbix 3.2.2
已有LNMP环境. 1.安装zabbix需要的依赖包,红色部门的包官方yum源没有,需要自己下载 yum install net-snmp fping iksemel net-snmp-devel ...
- Python之路 day2 字符编码及转换
#!/usr/bin/env python # -*- coding:utf-8 -*- #Author:ersa import sys print("sys default encodin ...
- 【burp】配置HTTPS抓包方法
以Chrome为例,配置HTTPS抓包方法 1.获取破解版的burp,将BurpLoader.jar和burpsuite_pro_v1.5.18.jar放到一个路径下 2.在cmd里进入上述两个jar ...
- linux主要的发行版及其区别和联系
1. 主要发行版 linux主要发行版有3类: (1).Debian (2).Slackware (3).Redhat (1)Debian Ubuntu 针对桌面和服务器 knopix 以安全著称 ( ...
- selenium遇到readonly元素的输入
方法:去掉该元素的readonly属性 使用js来去掉 ((JavaScriptExecutor ) driver).executeScript($("input#{放置元素的CLASS}[ ...