sql server 索引
来源:互联网 发布:时间轴网站源码 编辑:程序博客网 时间:2024/05/22 15:16
SQL SERVER 建立索引!
SQL Server 聚集索引/非聚集索引2011-03-26 19:55前些天看看 SQL Server 的聚集索引与非聚集索引的资料,拿来做做实现,分享一下心得。聚集索引: 该索引中键值的逻辑顺序决定了表中相应行的物理顺序。如果用 新华字典 作例子来一个例子的话。 [拼音]就可以看作是聚集索引 例如 吖、阿、啊 在字典的最前面。 左、作、坐 在字典的最后面。 拼音[逻辑顺序]很接近,在字典中页数的位置[物理顺序]也很接近。适用场合: 含有大量非重复值的列 使用BETWEEN,>,>=,<或<=返回一个范围值的列 被连续访问的列 返回大型结果集的查询 经常被使用连接或GROUP BY子句的查询访问的列非聚集索引: 非聚集索引与聚集索引一样有 B 树结构,但是有两个重大差别: 数据行不按非聚集索引键的顺序排序和存储。 非聚集索引的叶层不包含数据页。 相反,叶节点包含索引行。每个索引行包含非聚集键值以及一个或多个行定位器, 这些行定位器指向有该键值的数据行(如果索引不唯一,则可能是多行)。如果用 新华字典 作例子来一个例子的话。 [笔画]就可以看作是非聚集索引 例如 化 仇 仃 仅 仂 这几个字,都是 单人旁,笔画数相同的。 笔画[逻辑顺序]很接近,在字典中页数的位置[物理顺序]则在不同的位置上。适用场合: 含有大量非重复值的列 非连续访问的列 返回小型结果集的查询-- 由于 SQL SERVER 默认是在主键上建立聚集索引的。-- 一个表,又只允许有一个 聚集索引。-- 这里创建主键的时候,要指定这个主键,使用非聚集索引CREATE TABLE TestDoc( id INT identity(1, 1), createDate DATETIME, owner VARCHAR(10), docInfo TEXT, PRIMARY KEY NONCLUSTERED (id));go -- 首先插入 36500*5 = 182500 条数据.DECLARE @i AS INT, @myDate AS DATETIME;BEGIN SET @i = 0; SET @myDate = CONVERT(DATETIME, '1949.10.01', 102); WHILE @i < 36500 BEGIN SET @i = @i + 1; INSERT INTO TestDoc VALUES ( DATEADD(dd, @i, @myDate), '张三', NULL); INSERT INTO TestDoc VALUES ( DATEADD(dd, @i, @myDate), '李四', NULL); INSERT INTO TestDoc VALUES ( DATEADD(dd, @i, @myDate), '王五', NULL); INSERT INTO TestDoc VALUES ( DATEADD(dd, @i, @myDate), '赵六', NULL); INSERT INTO TestDoc VALUES ( DATEADD(dd, @i, @myDate), 'Admin', NULL); END;ENDgo-- 复制自己一次 = 182500 * 2 = 365000INSERT INTO TestDoc SELECT createDate, owner + '1', docInfo FROM TestDoc;go-- 再自己复制自己一次 = 365000 *2 = 730000INSERT INTO TestDoc SELECT createDate, owner + '2', docInfo FROM TestDoc;go-- 再自己复制自己一次 = 730000 *2 = 1460000INSERT INTO TestDoc SELECT createDate, owner + '3', docInfo FROM TestDoc;go-- 再自己复制自己一次 = 1460000 *2 = 2920000INSERT INTO TestDoc SELECT createDate, owner + '4', docInfo FROM TestDoc;go -- 用于测试执行性能的存储过程.-- 该存储过程,只在很大的数据量中,查询很少量的数据. [1/36500]CREATE PROCEDURE TestQuery1ASBEGIN SET NOCOUNT ON; IF EXISTS(SELECT * FROM sys.Tables WHERE name='#temp1') DROP TABLE #temp1; IF EXISTS(SELECT * FROM sys.Tables WHERE name='#temp2') DROP TABLE #temp2; -- 定义一个开始之间. DECLARE @startDate AS DATETIME; -- 首先只查询一个字段的 -- 设置 开始执行时间. SET @startDate = GETDATE(); -- 执行查询. SELECT * INTO #temp1 FROM TestDoc WHERE createDate = CONVERT(DATETIME, '2008.01.01', 102); -- 输出查询经过的时间. PRINT DATEDIFF(MS, @startDate, GETDATE()); -- 然后查询多个字段的 -- 设置 开始执行时间. SET @startDate = GETDATE(); -- 执行查询. SELECT * INTO #temp2 FROM TestDoc WHERE createDate = CONVERT(DATETIME, '2008.01.01', 102) AND owner LIKE '张三%'; -- 输出查询经过的时间. PRINT DATEDIFF(MS, @startDate, GETDATE());ENDgo-- 用于测试执行性能的存储过程.-- 该存储过程,在很大的数据量中,查询比较大量的数据. [1/100]CREATE PROCEDURE TestQuery2ASBEGIN SET NOCOUNT ON; IF EXISTS(SELECT * FROM sys.Tables WHERE name='#temp1') DROP TABLE #temp1; IF EXISTS(SELECT * FROM sys.Tables WHERE name='#temp2') DROP TABLE #temp2; -- 定义一个开始之间. DECLARE @startDate AS DATETIME; -- 首先只查询一个字段的 -- 设置 开始执行时间. SET @startDate = GETDATE(); -- 执行查询. SELECT * INTO #temp1 FROM TestDoc WHERE createDate >= CONVERT(DATETIME, '2008.01.01', 102) AND createDate < CONVERT(DATETIME, '2009.01.01', 102); -- 输出查询经过的时间. PRINT DATEDIFF(MS, @startDate, GETDATE()); -- 然后查询多个字段的 -- 设置 开始执行时间. SET @startDate = GETDATE(); -- 执行查询. SELECT * INTO #temp2 FROM TestDoc WHERE createDate >= CONVERT(DATETIME, '2008.01.01', 102) AND createDate < CONVERT(DATETIME, '2009.01.01', 102) AND owner LIKE '张三%'; -- 输出查询经过的时间. PRINT DATEDIFF(MS, @startDate, GETDATE());ENDgo-- 用于测试执行性能的存储过程.-- 该存储过程,在很大的数据量中,查询很大量的数据. [1/10]CREATE PROCEDURE TestQuery3ASBEGIN SET NOCOUNT ON; IF EXISTS(SELECT * FROM sys.Tables WHERE name='#temp1') DROP TABLE #temp1; IF EXISTS(SELECT * FROM sys.Tables WHERE name='#temp2') DROP TABLE #temp2; -- 定义一个开始之间. DECLARE @startDate AS DATETIME; -- 首先只查询一个字段的 -- 设置 开始执行时间. SET @startDate = GETDATE(); -- 执行查询. SELECT * INTO #temp1 FROM TestDoc WHERE createDate >= CONVERT(DATETIME, '1999.01.01', 102) AND createDate < CONVERT(DATETIME, '2009.01.01', 102); -- 输出查询经过的时间. PRINT DATEDIFF(MS, @startDate, GETDATE()); -- 然后查询多个字段的 -- 设置 开始执行时间. SET @startDate = GETDATE(); -- 执行查询. SELECT * INTO #temp2 FROM TestDoc WHERE createDate >= CONVERT(DATETIME, '1999.01.01', 102) AND createDate < CONVERT(DATETIME, '2009.01.01', 102) AND owner LIKE '张三%'; -- 输出查询经过的时间. PRINT DATEDIFF(MS, @startDate, GETDATE());ENDgo-- 在没有索引的情况下:EXECUTE TestQuery1;GOEXECUTE TestQuery2;GOEXECUTE TestQuery3;GO -- 创建非聚集索引CREATE NONCLUSTERED INDEX idx_TestDoc ON TestDoc(createDate);go-- 使用非聚集索引的情况下EXECUTE TestQuery1;GOEXECUTE TestQuery2;GOEXECUTE TestQuery3;GO-- 删除前面创建的索引DROP INDEX idx_TestDoc ON TestDoc;go-- 创建新的聚集索引CREATE CLUSTERED INDEX idx_TestDoc ON TestDoc(createDate);go-- 使用聚集索引的情况下EXECUTE TestQuery1;GOEXECUTE TestQuery2;GOEXECUTE TestQuery3;GO 最后的测试结果,大概的对比情况如下: 单位 毫秒数据百分比 无索引 非聚集 聚集1/36500 393-470 0-16 0-331/100 413-500 416-486 43-561/10 740-916 730-940 273-293测试的结果显示:在 返回大型结果集的查询 下使用非聚集索引,性能比没有索引的性能好不了多少,可能还会更差。使用聚集索引能够提高一定的性能。
来源:http://hi.baidu.com/wangzhiqing999/blog/item/ea57b6932325457854fb9634.html
- SQL server 索引
- 优化SQL Server索引
- 优化SQL Server索引
- SQL Server 索引碎片
- sql Server 索引优化
- SQL Server全文索引
- sql Server索引优化
- sql Server 索引优化
- SQL Server创建索引
- SQL Server 索引维护
- Sql Server 索引
- SQL Server索引原则
- SQL Server 索引分析
- SQL Server中索引
- sql server 索引入门
- SQL Server索引原则
- 深入浅出SQL Server索引
- SQL Server全文索引
- memcached简单的使用教程
- javascript 模拟滚动条
- Oracle数据库安装及创建表
- Android应用开发提高系列(1)——《Practical Java 中文版》读书笔记(上)
- C#这样给一个对象赋
- sql server 索引
- Java 实现XML反序列化成class
- 设计模式 reactor和proactor
- JS右键菜单
- android camera主要文件
- jQuery上传插件Uploadify使用详解
- Windows Server 2008 安装SQL Server 2008 报错:必须使用“角色管理工具”安装或配置Microsoft .NET Framework 3.5 SP1
- 求解HIBERNATE大家试过级联保存
- JSP 中 reponse.sendRedirect 多次调用后的bug