索引的重要性

数据库性能优化中索引绝对是一个重量级的因素,可以说,索引使用不当,其它优化措施将毫无意义。

聚簇索引(Clustered Index)和非聚簇索引(Non- Clustered Index)

最通俗的解释是:聚簇索引的顺序就是数据的物理存储顺序,而对非聚簇索引的索引顺序与数据物理排列顺序无关。举例来说,你翻到新华字典的汉字“爬”那一页就是P开头的部分,这就是物理存储顺序(聚簇索引);而不用你到目录,找到汉字“爬”所在的页码,然后根据页码找到这个字(非聚簇索引)。

下表给出了何时使用聚簇索引与非聚簇索引:

动作

使用聚簇索引

使用非聚簇索引

列经常被分组排序

返回某范围内的数据

不应

一个或极少不同值

不应

不应

小数目的不同值

不应

大数目的不同值

不应

频繁更新的列

不应

外键列

主键列

频繁修改索引列

不应

聚簇索引的唯一性

正式聚簇索引的顺序就是数据的物理存储顺序,所以一个表最多只能有一个聚簇索引,因为物理存储只能有一个顺序。正因为一个表最多只能有一个聚簇索引,所以它显得更为珍贵,一个表设置什么为聚簇索引对性能很关键。

初学者最大的误区:把主键自动设为聚簇索引

因为这是SQLServer的默认主键行为,你设置了主键,它就把主键设为聚簇索引,而一个表最多只能有一个聚簇索引,所以很多人就把其他索引设置为非聚簇索引。这个是最大的误区。甚至有的主键又是无意义的自动增量字段,那样的话Clustered index对效率的帮助,完全被浪费了。

刚才说到了,聚簇索引性能最好而且具有唯一性,所以非常珍贵,必须慎重设置。一般要根据这个表最常用的SQL查询方式来进行选择,某个字段作为聚簇索引,或组合聚簇索引,这个要看实际情况。

事实上,建表的时候,先需要设置主键,然后添加我们想要的聚簇索引,最后设置主键,SQLServer就会自动把主键设置为非聚簇索引(会自动根据情况选择)。如果你已经设置了主键为聚簇索引,必须先删除主键,然后添加我们想要的聚簇索引,最后恢复设置主键即可。

记住我们的最终目的就是在相同结果集情况下,尽可能减少逻辑IO。

我们先从一个实际使用的简单例子开始。

一个简单的表:

CREATE TABLE [dbo].[Table1](

[ID] [int] IDENTITY(1,1) NOT NULL,

[Da

ta1] [int] NOT NULL DEFAULT ((0)),

[Da

ta2] [int] NOT NULL DEFAULT ((0)),

[Da

ta3] [int] NOT NULL DEFAULT ((0)),

[Name1] [nvarchar](50) NOT NULL DEFAULT (''),

[Name2] [nvarchar](50) NOT NULL DEFAULT (''),

[Name3] [nvarchar](50) DEFAULT (''),

[DTAt] [datetime] NOT NULL DEFAULT (getdate())

复制代码

来点测试数据(10w条):

declare @i int

set @i = 1

while @i < 100000

begin

insert into Table1 ([Da

ta1] ,[Da

ta2] ,[Da

ta3] ,[Name1],[Name2] ,[Name3])

values(@i , 2* @i ,3*@i, CAST(@i AS NVARCHAR(50)), CAST(2*@i AS NVARCHAR(50)), CAST(3*@i AS NVARCHAR(50)))

set @i = @i + 1

end

update table1 set dtat= DateAdd (s, da

ta1, dtat)

复制代码

打开查询分析器的IO统计和时间统计:

SET STATISTICS IO ON;

SET STATISTICS TIME ON;

复制代码

显示实际的“执行计划”:

我们最常用的SQL查询是这样的:

SELECT * FROM Table1 WHERE Da

ta1 = 2 ORDER BY DTAt DESC;

复制代码

先在Table1设主键ID,系统自动为该主键建立了聚簇索引。

然后执行该语句,结果是:

Table 'Table1'. Scan count 1, logical reads 911, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:

CPU time = 16 ms, elapsed time = 7 ms.

复制代码

然后我们在Data1和DTat字段分别建立非聚簇索引:

CREATE NONCLUSTERED INDEX [N_Da

ta1] ON [dbo].[Table1]

(

[Da

ta1] ASC

)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ON

LINE = OFF) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [N_DTat] ON [dbo].[Table1]

(

[DTAt] ASC

)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ON

LINE = OFF) ON [PRIMARY]

复制代码

再次执行该语句,结果是:

Table 'Table1'. Scan count 1, logical reads 5, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:

CPU time = 0 ms, elapsed time = 39 ms.

复制代码

可以看到设立了索引反而没有任何性能的提升而且消耗的时间更多了,继续调整。

然后我们删除所有非聚簇索引,并删除主键,这样所有索引都删除了。建立组合索引Data1和DTAt,最后加上主键:

CREATE CLUSTERED INDEX [C_Da

ta1_DTat] ON [dbo].[Table1]

(

[Da

ta1] ASC,

[DTAt] ASC

)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ON

LINE = OFF) ON [PRIMARY]

复制代码

再次执行语句:

Table 'Table1'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:

CPU time = 0 ms, elapsed time = 1 ms.

复制代码

可以看到只有聚簇索引seek了,消除了index scan和nested loop,而且执行时间也只有1ms,达到了最初优化的目的。

组合索引小结

小结以上的调优实践,要注意聚簇索引的选择。首先我们要找到我们最多用到的SQL查询,像本例就是那句类似的组合条件查询的情况,这种情况最好使用组合聚簇索引,而且最多用到的字段要放在组合聚簇索引的前面,否则的话就索引就不会有好的效果,看下例:

查询条件落在组合索引的第二个字段上,引起了index scan,效果很不好,执行时间是:

Table 'Table1'. Scan count 1, logical reads 238, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:

CPU time = 16 ms, elapsed time = 22 ms.

复制代码

而如果仅查询条件是第一个字段也没有问题,因为组合索引最左前缀原则,实践如下:

Table 'Table1'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:

CPU time = 0 ms, elapsed time = 1 ms.

复制代码

从中可以看出,最多用到的字段要放在组合聚簇索引的前面。

Index seek 为什么比 Index scan好?

索引扫描也就是遍历B树,而seek是B树查找直接定位。

Index scan多半是出现在索引列在表达式中。数据库引擎无法直接确定你要的列的值,所以只能扫描整个整个索引进行计算。index seek就要好很多.数据库引擎只需要扫描几个分支节点就可以定位到你要的记录。回过来,如果聚集索引的叶子节点就是记录,那么Clustered Index Scan就基本等同于full table scan。

一些优化原则

1、缺省情况下建立的索引是非聚簇索引,但有时它并不是最佳的。在非群集索引下,数据在物理上随机存放在数据页上。合理的索引设计要建立在对各种查询的分析和预测上。一般来说:

a.有大量重复值、且经常有范围查询( > ,< ,> =,< =)和order by、group by发生的列,可考

虑建立群集索引;

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

c.组合索引要尽量使关键查询形成索引覆盖,其前导列一定是使用最频繁的列。索引虽有助于提高性能但不是索引越多越好,恰好相反过多的索引会导致系统低效。用户在表中每加进一个索引,维护索引集合就要做相应的更新工作。

2、ORDER BY和GROPU BY使用ORDER BY和GROUP BY短语,任何一种索引都有助于SELECT的性能提高。

3、多表操作在被实际执行前,查询优化器会根据连接条件,列出几组可能的连接方案并从中找出系统开销最小的最佳方案。连接条件要充份考虑带有索引的表、行数多的表;内外表的选择可由公式:外层表中的匹配行数*内层表中每一次查找的次数确定,乘积最小为最佳方案。

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

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

Sql的优化原则2:

1、只要能满足你的需求,应尽可能使用更小的数据类型:例如使用MEDIUMINT代替INT

2、尽量把所有的列设置为NOT NULL,如果你要保存NULL,手动去设置它,而不是把它设为默认值。

3、尽量少用VARCHAR、TEXT、BLOB类型

4、如果你的数据只有你所知的少量的几个。最好使用ENUM类型

使用SQLServer Profiler找出数据库中性能最差的SQL

首先打开SQLServer Profiler:

然后点击工具栏“New Trace”,使用默认的模板,点击RUN。

也许会有报错:"only TrueType fonts are supported. There id not a TrueType font"。不用怕,点击Tools菜单->Options,重新选择一个字体例如Vendana 即可。(这个是微软的一个bug)

运行起来以后,SQLServer Profiler会监控数据库的活动,所以最好在你需要监控的数据库上多做些操作。等觉得差不多了,点击停止。然后保存trace结果到文件或者table。

这里保存到Table:在菜单“File”-“Save as ”-“Trace table”,例如输入一个master数据库的新的table名:profileTrace,保存即可。

找到最耗时的SQL:

use master

select * from profiletrace order by duration desc;

复制代码

找到了性能瓶颈,接下来就可以有针对性的一个个进行调优了。

对使用SQLServer Profiler的更多信息可以参考:

http://www.codeproject.com/KB/database/DiagnoseProblemsSQLServer.aspx

使用SQLServer Database Engine Tuning Advisor数据库引擎优化顾问

使用上述的SQLServer Profiler得到了trace还有一个好处就是可以用到这个优化顾问。用它可以偷点懒,得到SQLServer给您的优化顾问,例如这个表需要加个索引什么的…

首先打开数据库引擎优化顾问:

然后打开刚才profiler的结果(我们存到了master数据库的profileTrace表):

点击“start analysis”,运行完成后查看优化建议(图中最后是建议建立的索引,性能提升72%)

这个方法可以偷点懒,得到SQLServer给您的优化顾问。

oracle非聚簇索引,聚簇索引(Clustered Index)和非聚簇索引 (Non- Clustered Index)相关推荐

  1. 聚簇索引(Clustered Index)和非聚簇索引 (Non-Clustered Index)

    索引的重要性 数据库性能优化中索引绝对是一个重量级的因素,可以说,索引使用不当,其它优化措施将毫无意义. 聚簇索引(Clustered Index)和非聚簇索引 (Non-Clustered Inde ...

  2. 聚簇索引(Clustered Index)和非聚簇索引 (Non- Clustered Index)

    本文转自https://my.oschina.net/u/1866821/blog/297673 索引的重要性 数据库性能优化中索引绝对是一个重量级的因素,可以说,索引使用不当,其它优化措施将毫无意义 ...

  3. 聚簇索引(Clustered Index)和非聚簇索引分析与sql server查询优化

    本文转自https://my.oschina.net/u/1866821/blog/297673 索引的重要性 数据库性能优化中索引绝对是一个重量级的因素,可以说,索引使用不当,其它优化措施将毫无意义 ...

  4. SQL Server中的聚集索引(clustered index) 和 非聚集索引 (non-clustered index)

    1. 什么是聚合索引(clustered index) / 什么是非聚合索引(nonclustered index)? 2. 聚合索引和非聚合索引有什么区别? 深入浅出理解索引结构 实际上,您可以把索 ...

  5. 聚合索引(clustered index) 和 非聚合索引(nonclustered index)

    以下我面试经常问的2道题..尤其针对觉得自己SQL SERVER 还不错的同志.. 呵呵 很难有人答得好..  各位在我收集每个人擅长的东西时,大部分都把SQL SERVER 标为Expert,看看是 ...

  6. oracle 包和包体禁用,Oracle包和包体以及与非包体定义函数、过程的区别

    Oracle包和包体以及与非包体定义函数.过程的区别. 1.Oracle中的包和包体 Oracle中的包和包体与java中的接口和类才关系特别类似,我们就根据对比学习一下包和包体吧! 2.oracle ...

  7. Oracle执行计划。RBO优化器和CBO优化器。TABLE ACCESS FULL,TABLE ACCESS BY INDEX ROWID,TABLE ACCESS BY INDEX SCAN

    文章目录 通过PL/SQL Developer查看查询的执行计划 1. 什么是执行计划 2. 配置执行计划需要显示的项 3执行计划的常用列字段解释 4. 使用执行计划 5. 查看执行计划 5.1 执行 ...

  8. 【组合数学】非降路径问题 ( 非降路径问题概要说明 | 非降路径问题基本模型 | 非降路径问题拓展模型 1 非原点起点 | 非降路径问题拓展模型 2 有途经点 )

    文章目录 一.非降路径问题 概要说明 二.非降路径问题 基本模型 二.非降路径问题 拓展模型 1 三.非降路径问题 拓展模型 2 组合恒等式参考博客 : [组合数学]二项式定理与组合恒等式 ( 二项式 ...

  9. 精算模型10 非参数模型0 精算数据、非参数建模的思路概述

    精算模型10 非参数模型0 精算数据.非参数建模的目标概述 数据类型 完整数据 非完整数据 数据分析目标 这是精算模型的第十部分,精算的非参数统计模型,从这一部分开始我们讨论精算建模的统计方法.在讨论 ...

最新文章

  1. 开发日记-20190816 关键词 读书笔记《Linux 系统管理技术手册(第二版)》DAY 24
  2. Google 图片搜索的原理是什么?
  3. Windows打印机驱动开发笔记(一)
  4. java socket tomcat_在Tomcat环境下使用socket通信
  5. 数独游戏技巧从入门到精通_中国茶艺技巧:500集从入门到精通教程,视频+素材+笔记...
  6. JavaScript高级程序设计之客户端检测
  7. 0603 0402 0805 电阻封装寸尺
  8. 重新发现 make: 规则背后的力量
  9. buntu下shell脚本运行异常:bash和…
  10. PAT乙级1005. 继续(3n+1)猜想 (25)
  11. MLOps- 吴恩达Andrew Ng Overview of the ML Lifecycle and Deployment Week1 论文等资料汇总
  12. 多视角子空间学习系列之 CCA 典型相关分析
  13. vb.net 教程 6-1 进程 Process类初探
  14. macpro如何清理磁盘空间_如何在Mac上清除磁盘空间(2020年最佳技巧)
  15. 计算机显示器分辨率,电脑显示器分辨率调多少合适
  16. 微博吃瓜总是晚一步才知道,程序员直接写了一个热搜提醒工具
  17. Thales Speakers Bureau:专家云集,将探讨量子技术、5G、数字身份、网络安全和人工智能
  18. 纯CSS画基本图形(矩形、圆形、三角形、多边形、爱心)
  19. 华笔记本linux系统方便吗,买华为国产Linux系统笔记本电脑的几个好处
  20. Unity3D灯光与渲染学习之(一):天空盒、灯光以及色彩空间

热门文章

  1. 称密码、非对称密码、散列算法与 PKI
  2. PHP 中高级程序员面试模拟题
  3. 创业公司公关和危机管理必读
  4. 每周分享第 14 期(20190222)
  5. 自定义加密算法打造不死网马
  6. 数据库基本概念和常用SQL命令
  7. ZooKeeper源码分析-Jute-第二部分
  8. 【数项级数】无穷个数相加一定是个数吗?
  9. openstack集群安装(Rocky版)
  10. pycharm怎么设置自己喜欢的背景