我如何调优SQL Server查询

发表于:2015-8-07 09:34

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Woodytu    来源:51Testing软件测试网采编

  SQL Server现在在非聚集索引上进行了查找操作,但在执行计划里我们还有排序(Sort)运算符。因为基数计算30%的硬编码,排序(Sort)还是要蔓延到TempDb。偶滴神!我们的逻辑读已经降到了757,但运行时间还是近800毫秒。你现在应该怎么做?
  现在我们可以尝试在非聚集索引的导航结构直接包含CarrierTrackingNumber列。这是SQL Server进行排序运算符的列。当我们在非聚集索引直接加了这列(作为主键),我们就物理排序了那列,因此排序(Sort)运算符应该会消失。作为积极的副作用,也不会蔓延到TempDb。在执行计划里,现在也没有运算符关心错误的基数计算。因此我们尝试那个假设,再次重建非聚集索引:
  1 CREATE NONCLUSTERED INDEX idx_Test ON Sales.SalesOrderDetail(CarrierTrackingNumber, ProductID)
  2 INCLUDE (OrderQty, UnitPrice, UnitPriceDiscount)
  3 WITH
  4 (
  5     DROP_EXISTING = ON
  6 )
  7 GO
  从索引定义可以看到,现在我们已经对CarrierTrackingNumber和ProductID列的数据物理预排序。当你再次重新执行查询,在你查看执行计划时,你会看到排序(Sort)运算符已经消失,SQL Server扫描了非聚集索引的整个叶子层(使用剩余谓语(residual predicate)作为搜索谓语)。
  这个执行计划并不坏!我们只需要763个逻辑读,现在的运行时间已经降至600毫秒。和刚才的相比已经有25%的改善!但是:查询优化器建议我们一个更好的非聚集索引,通过缺少索引建议(Missing Index Recommendations)!暂且相信下,我们创建建议的非聚集索引:
  1 CREATE NONCLUSTERED INDEX [SQL Server doesn't care about names, why I should care about names?]
  2 ON [Sales].[SalesOrderDetail] ([ProductID])
  3 INCLUDE ([SalesOrderID],[SalesOrderDetailID],[CarrierTrackingNumber],[OrderQty],[LineTotal])
  4 GO
  当你现在重新执行最初的查询,你会发现令人惊讶的事情:查询优化器使用“我们”刚才创建的非聚集索引,缺少索引建议已经消失!
  你刚刚创建了SQL Server从不使用的索引——除了INSERT,UPDATE和DELETE语句,SQL Server都要去维护你的非聚集索引。对于你的数据库,你刚创建了“单纯”浪费空间的索引。当另一方面,你已经通过消除丢失索引建议,满足了查询优化器。但这不是目的:目的是创建会被再次使用的索引。
  结论:永不相信查询优化器!
  小结
  今天的文章有点争议性,但我想你向你展示下,但你在创建索引时,查询优化器如何帮助你,还有查询优化器如何愚弄你。因此做出小的调整,就立即运行你的查询,验证改变非常重要。还有当你使用来查询优化器的缺少索引建议时,请考虑下这个建议是个好的么。额,我已经说过——我会直接咔嚓掉。呵呵~~~
22/2<12
《2023软件测试行业现状调查报告》独家发布~

精彩评论

  • BDYD
    2015-8-08 00:33:15

    **于达校区严格遵循**总部的教学体系,秉承**“教育改变生活”理念,传承**“源自北大,永不妥协的教育品质”精神,集**于达校区多年经验,为上海地区**总部唯一授权软件测试培训中心,是**多课程高质量高就业校区。
    选择上海**,教育改变生活!选择**于达校区,成就你我!

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号