热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:5级阶梯SQLServer索引

篇首语:本文由编程笔记#小编为大家整理,主要介绍了5级阶梯SQLServer索引相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了5级阶梯SQL Server索引相关的知识,希望对你有一定的参考价值。


本文是楼梯系列的一部分:SQL Server的阶梯索引

索引数据库设计的基础,告诉开发人员使用数据库设计者的意图。 不幸的是索引时往往是后加上的性能问题出现。 终于在这里是一个简单的系列文章,让任何数据库专业迅速“加速”

前水平介绍聚集和非聚集索引,每个突出以下方面:



  • 总有一个入口在索引表中的每一行(我们指出一个例外规则将在稍后的水平)。 这些条目总是在索引键序列。

  • 在聚集索引中,表的索引条目是实际的行。

  • 非聚集索引的条目是独立于数据行; 包括索引键列和书签索引键列映射到实际的价值表的行。

最后的一半以前的句子是正确的,但是不完整。 在这个层次,我们检查选项包括附加列集群指数,包括列。 在6级检查书签操作,我们将看到,SQL Server可能单方面将一些列添加到您的索引。


包括列

非聚集索引的列,但不是索引键的一部分,被称为包括列。 这些列不是关键的一部分,所以不影响索引条目的顺序。 同时,正如我们将看到的,它们会引起较少的开销比键列。

当创建一个非聚集索引,我们指定包含分开列键列; 如清单5.1所示。

CREATE NONCLUSTERED INDEX FK_ProductID_ ModifiedDate
       ON Sales.SalesOrderDetail (ProductID, ModifiedDate)
       INCLUDE (OrderQty, UnitPrice, LineTotal)

 

清单5.1:创建一个非聚集索引,包括列

在这个例子中,ProductIDModifiedDate是索引键列,OrderQty,UnitPriceLineTotal是包含的列。

如果我们不指定了呢包括条款在上面的SQL语句,生成的指数会看起来像这样:

ProductID   ModifiedDate   Bookmark

Page n:

707         2004/07/25        =>  
707         2004/07/26        =>  
707         2004/07/26        =>  
707         2004/07/26        =>  
707         2004/07/27        =>  
707         2004/07/27        =>  
707         2004/07/27        =>  
707         2004/07/28        =>  
707         2004/07/28        =>  
707         2004/07/28        =>  
707         2004/07/28        =>  
707         2004/07/28        =>  
707         2004/07/28        =>  

Page n+1:

707         2004/07/29        =>  
707         2004/07/31        =>  
707         2004/07/31        =>  
707         2004/07/31        =>  
708         2001/07/01        =>  
708         2001/07/01        =>  
708         2001/07/01        =>  
708         2001/07/01        =>  
708         2001/07/01        =>  
708         2001/07/01        =>  
708         2001/07/01        =>  
708         2001/07/01        =>  
708         2001/07/01        =>  
708         2001/07/01        =>  

However, having told SQL Server to include the OrderQty, UnitPrice and LineTotal columns, the index looks like this:

:- Search Key Columns -:      :---  Included Columns  ---:     : Bookmark :

ProductID   ModifiedDate      OrderQty    UnitPrice   LineTotal       

Page n-1:

707         2004/07/29        1           34.99       34.99       =>  
707         2004/07/31        1           34.99       34.99       =>  
707         2004/07/31        3           34.99      104.97       =>  
707         2004/07/31        1           34.99       34.99       =>  
708         2001/07/01        5           20.19      100.95       =>  

Page n:

708         2001/07/01        1           20.19       20.19       =>  
708         2001/07/01        1           20.19       20.19       =>  
708         2001/07/01        2           20.19       40.38       =>  
708         2001/07/01        1           20.19       20.19       =>  
708         2001/07/01        2           20.19       40.38       =>  

708         2001/12/01        7           20.19      141.33       =>  
708         2001/12/01        1           20.19       20.19       =>  
708         2002/01/01        1           20.19       20.19       =>  
708         2002/01/01        1           20.19       20.19       =>  
708         2002/01/01        1           20.19       20.19       =>  

Page n+1:

708         2002/01/01        2           20.19       40.38       =>  
708         2002/01/01        5           20.19      100.95       => 
 
708         2002/02/01        1           20.19       20.19       =>  
708         2002/02/01        1           20.19       20.19       =>  
708         2002/02/01        2           20.19       40.38       =>  

检查这个指数显示的内容,很明显,索引键列的行命令。 五行产品与修改日期708年1月1日2002(以粗体突出显示),例如,在索引中是连续的,其他的行ProductID/ModifiedDate组合。

你可能会问“为什么甚至包括列? 为什么不简单地添加OrderQty,UnitPriceLineTotal索引键? “有几个优势在这些列索引中而不是在索引键,如:



  • 列不属于索引键的位置不影响在索引条目。 反过来,这降低了他们的开销在索引中。 例如,如果ProductIDModifiedDate价值行修改,那么这一行在索引的条目必须搬迁。 但是,如果UnitPricevalue行修改,索引条目仍然需要更新,但它不需要感动。

  • 所需的努力找到一个条目(s)指数更少。

  • 指数的大小将会略小。

  • 索引的数据分布统计信息将更容易维护。

大部分这些优势将更有意义的晚年的水平,当我们观察内部结构的索引和一些额外的信息由SQL Server维护优化查询性能。

决定是否一个索引列索引键的一部分,或只是一个包含列,索引不是最重要的决定你会做。 也就是说,经常出现在列选择但不是在列表在哪里子句的查询最好放置在包含的列索引的一部分。


在成为一个覆盖指数

在四级,我们表示赞同的设计者AdventureWorksdatabase关于他们的决定SalesOrderID/SalesOrderDetailID的聚集索引SalesOrderDetail表。 大多数查询该表将请求数据命令或按销售订单分组号。 然而,一些查询,也许从仓库人员,需要在产品序列的信息。 这些查询将受益于该指数如清单5.1所示。

说明的潜在好处包括列索引,我们将着眼于对SalesOrderDetailtable两个查询,我们将执行三次,如下:



  • 1:运行没有非聚集索引

  • 运行2:使用非聚集索引不包含包含列(只有两个键列)

  • 运行3:使用非聚集索引如清单5.1中定义的

当我们在先前的水平,我们再次使用读取数作为主要的指标,但我们也使用SQL Server Management Studio的“显示实际执行计划”选项来查看每个执行的计划。 这将给我们一个额外的度量:工作量的百分比是花在non-read活动,如匹配相关数据后,读取到内存中。 这给了我们更好的理解查询的总成本。


测试第一个查询:活动产品的总数

我们的第一个查询,如清单5.2所示,是一个提供活动总数按日期为一个特定的产品。

SELECT  ProductID ,
        ModifiedDate ,
        SUM(OrderQty) AS ‘No of Items‘ ,
        AVG(UnitPrice) ‘Avg Price‘ ,
        SUM(LineTotal) ‘Total Value‘
FROM    Sales.SalesOrderDetail
WHERE   ProductID = 888
GROUP BY ProductID ,
        ModifiedDate ;

 

清单5.2:“产品”活动总数查询

因为索引可以影响一个查询的性能,而不是结果; 对三种不同的索引方案执行这个查询总收益率以下行设置:

ProductID ModifiedDate Avg的行没有价格总额

ProductID   ModifiedDate    No of Rows  Avg Price         Total Value

----------- ------------    ----------- -----------------------------
888         2003-07-01      16          602.346           9637.536000
888         2003-08-01      13          602.346           7830.498000
888         2003-09-01      19          602.346           11444.574000
888        2003-10-01       2           602.346           1204.692000
888         2003-11-01      17          602.346           10239.882000
888         2003-12-01      4           602.346           2409.384000
888         2004-05-01      10          602.346           6023.460000
888         2004-06-01      2           602.346           1204.692000

The eight rows of output are aggregated from the thirty nine ‘ProductID = 888’ rows in the table to give one output row for each date that had one-or-more ‘ProductID = 888’ sales.The basic scheme for conducting our test is shown in Listing 5.3. Before you run any queries, make sure you run SET STATISTICS IO ON.

IF EXISTS ( SELECT  1
            FROM    sys.indexes
            WHERE   name = ‘FK_ProductID_ModifiedDate‘
                    AND OBJECT_ID = OBJECT_ID(‘Sales.SalesOrderDetail‘) )
    DROP INDEX Sales.SalesOrderDetail.FK_ProductID_ModifiedDate ;
GO
--RUN 1: Execute Listing 5.2 here (no non-clustered index)
CREATE NONCLUSTERED INDEX FK_ProductID_ModifiedDate
ON Sales.SalesOrderDetail (ProductID, ModifiedDate) ;
--RUN 2: Re-execute Listing 5.2 here (non-clustered index with no include)
IF EXISTS ( SELECT  1
            FROM    sys.indexes
            WHERE   name = ‘FK_ProductID_ModifiedDate‘
                    AND OBJECT_ID = OBJECT_ID(‘Sales.SalesOrderDetail‘) )
    DROP INDEX Sales.SalesOrderDetail.FK_ProductID_ModifiedDate ;
GO
CREATE NONCLUSTERED INDEX FK_ProductID_ModifiedDate
ON Sales.SalesOrderDetail (ProductID, ModifiedDate)
INCLUDE (OrderQty, UnitPrice, LineTotal) ;
--RUN 3: Re-execute Listing 5.2 here (non-clustered index with include)

 

运行测试,遵循相同的模式如清单5.3所述,但使用新的查询清单5.4。 结果所需的相关工作执行查询每个索引方案如表5.2所示。

















1:运行

没有非聚集索引


表“SalesOrderDetail”。 扫描数1,逻辑读1238。

非阅读活动:10%。


运行2:

——不包括列建立索引


表“SalesOrderDetail”。 扫描数1,逻辑读1238。

非阅读活动:10%。


运行3:

包括列


表“SalesOrderDetail”。 扫描数1,逻辑读761。

非阅读活动:8%。


表2:运行第二个查询结果三次不同的非聚集索引可用

第一次和第二次测试导致相同的计划; 一个完整的扫描theSalesOrderDetail表。 原因在四级,详细介绍在哪里条款不足够选择性受益于non-covering指数。 行包括任何一组也分散在桌子上。 表被读,每一行必须匹配组; 和操作处理器时间和内存消耗。

第三个测试发现在非聚集索引所需的一切; 但不像前面的查询,它没有发现内的连续行位于索引。 他行组成每个组内是连续的指数; 但组织本身是分散在索引的长度。 因此,SQL Server扫描索引。

扫描索引的表有两个优点:



  • 该指数小于表,需要更少的读取。

  • 行已经分组,需要更少的非阅读活动。


结论

包括列使非聚集索引成为各种覆盖索引查询,提高这些查询的性能; 有时会很显著。 包括列增加一个索引的大小,但添加其他小的开销。 任何时候你正在创建一个非聚集索引,特别是在一个外键列时,问问自己——“我该怎么附加列包含在这个索引吗?”

原文链接:http://www.sqlservercentral.com/articles/Stairway+Series/72276/



















































推荐阅读
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
  • 深入解析Android 4.4中的Fence机制及其应用
    在Android 4.4中,Fence机制是处理缓冲区交换和同步问题的关键技术。该机制广泛应用于生产者-消费者模式中,确保了不同组件之间高效、安全的数据传输。通过深入解析Fence机制的工作原理和应用场景,本文探讨了其在系统性能优化和资源管理中的重要作用。 ... [详细]
  • SQL 查询实体优化与实战技巧分享 ... [详细]
  • 本文介绍了如何利用ObjectMapper实现JSON与JavaBean之间的高效转换。ObjectMapper是Jackson库的核心组件,能够便捷地将Java对象序列化为JSON格式,并支持从JSON、XML以及文件等多种数据源反序列化为Java对象。此外,还探讨了在实际应用中如何优化转换性能,以提升系统整体效率。 ... [详细]
  • 在Ubuntu上安装MySQL时解决缺少libaio.so.1错误及libaio在MySQL中的重要性分析
    在Ubuntu系统上安装MySQL时,遇到了缺少libaio.so.1的错误。本文详细介绍了如何解决这一问题,并深入探讨了libaio库在MySQL性能优化中的重要作用。对于初学者而言,理解这些依赖关系和配置步骤是成功安装和运行MySQL的关键。通过本文的指导,读者可以顺利解决相关问题,并更好地掌握MySQL在Linux环境下的部署与管理。 ... [详细]
  • 开发日志:201521044091 《Java编程基础》第11周学习心得与总结
    开发日志:201521044091 《Java编程基础》第11周学习心得与总结 ... [详细]
  • 在Android应用开发中,实现与MySQL数据库的连接是一项重要的技术任务。本文详细介绍了Android连接MySQL数据库的操作流程和技术要点。首先,Android平台提供了SQLiteOpenHelper类作为数据库辅助工具,用于创建或打开数据库。开发者可以通过继承并扩展该类,实现对数据库的初始化和版本管理。此外,文章还探讨了使用第三方库如Retrofit或Volley进行网络请求,以及如何通过JSON格式交换数据,确保与MySQL服务器的高效通信。 ... [详细]
  • 本指南从零开始介绍Scala编程语言的基础知识,重点讲解了Scala解释器REPL(读取-求值-打印-循环)的使用方法。REPL是Scala开发中的重要工具,能够帮助初学者快速理解和实践Scala的基本语法和特性。通过详细的示例和练习,读者将能够熟练掌握Scala的基础概念和编程技巧。 ... [详细]
  • Python内置模块详解:正则表达式re模块的应用与解析
    正则表达式是一种强大的文本处理工具,通过特定的字符序列来定义搜索模式。本文详细介绍了Python内置的`re`模块,探讨了其在字符串匹配、验证和提取中的应用。例如,可以通过正则表达式验证电子邮件地址、电话号码、QQ号、密码、URL和IP地址等。此外,文章还深入解析了`re`模块的各种函数和方法,提供了丰富的示例代码,帮助读者更好地理解和使用这一工具。 ... [详细]
  • 提升Android开发效率:Clean Code的最佳实践与应用
    在Android开发中,提高代码质量和开发效率是至关重要的。本文介绍了如何通过Clean Code的最佳实践来优化Android应用的开发流程。以SQLite数据库操作为例,详细探讨了如何编写高效、可维护的SQL查询语句,并将其结果封装为Java对象。通过遵循这些最佳实践,开发者可以显著提升代码的可读性和可维护性,从而加快开发速度并减少错误。 ... [详细]
  • Python进阶笔记:深入理解装饰器、生成器与迭代器的应用
    本文深入探讨了Python中的装饰器、生成器和迭代器的应用。装饰器本质上是一个函数,用于在不修改原函数代码和调用方式的前提下为其添加额外功能。实现装饰器需要掌握闭包、高阶函数等基础知识。生成器通过 `yield` 语句提供了一种高效生成和处理大量数据的方法,而迭代器则是一种可以逐个访问集合中元素的对象。文章详细解析了这些概念的原理和实际应用案例,帮助读者更好地理解和使用这些高级特性。 ... [详细]
  • 在使用 SQL Server 时,连接故障是用户最常见的问题之一。通常,连接 SQL Server 的方法有两种:一种是通过 SQL Server 自带的客户端工具,例如 SQL Server Management Studio;另一种是通过第三方应用程序或开发工具进行连接。本文将详细分析导致连接故障的常见原因,并提供相应的解决策略,帮助用户有效排除连接问题。 ... [详细]
  • 在使用SSH框架进行项目开发时,经常会遇到一些常见的问题。例如,在Spring配置文件中配置AOP事务声明后,进行单元测试时可能会出现“No Hibernate Session bound to thread”的错误。本文将详细探讨这一问题的原因,并提供有效的解决方案,帮助开发者顺利解决此类问题。 ... [详细]
  • 本文总结了JavaScript的核心知识点和实用技巧,涵盖了变量声明、DOM操作、事件处理等重要方面。例如,通过`event.srcElement`获取触发事件的元素,并使用`alert`显示其HTML结构;利用`innerText`和`innerHTML`属性分别设置和获取文本内容及HTML内容。此外,还介绍了如何在表单中动态生成和操作``元素,以便更好地处理用户输入。这些技巧对于提升前端开发效率和代码质量具有重要意义。 ... [详细]
  • 【图像分类实战】利用DenseNet在PyTorch中实现秃头识别
    本文详细介绍了如何使用DenseNet模型在PyTorch框架下实现秃头识别。首先,文章概述了项目所需的库和全局参数设置。接着,对图像进行预处理并读取数据集。随后,构建并配置DenseNet模型,设置训练和验证流程。最后,通过测试阶段验证模型性能,并提供了完整的代码实现。本文不仅涵盖了技术细节,还提供了实用的操作指南,适合初学者和有经验的研究人员参考。 ... [详细]
author-avatar
kaga1990_106
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有