广告
返回顶部
首页 > 资讯 > 数据库 >如何调优SQL Server查询
  • 916
分享到

如何调优SQL Server查询

2024-04-02 19:04:59 916人浏览 八月长安
摘要

这期内容当中小编将会给大家带来有关如何调优SQL Server查询,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。在今天的文章里,我想给你展示下,当你想对特定查询创建索引设

这期内容当中小编将会给大家带来有关如何调优SQL Server查询,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

在今天的文章里,我想给你展示下,当你想对特定查询创建索引设计时,如何把你的工作和思考过程传达给查询优化器。下面就一起来探讨一下吧!

有问题的查询我们来看下列查询:

 DECLARE @i INT = 999 SELECT   SalesOrderID,    SalesOrderDetailID,   CarrierTrackingNumber,    OrderQty,    LineTotal FROM Sales.SalesOrderDetail WHERE ProductID < @i ORDER BY CarrierTrackingNumber Go

如你所见,这里用了一个本地变量与一个不等于谓语来从Sales.SalesOrderDetail表来获取一些记录。当你执行那个查询,看它的执行计划时,你会发现它有一些严重的问题:

sql Server需要扫描Sales.SalesOrderDetail表的整个非聚集索引,因为没有支持的非聚集索引。对这个扫描,查询需要1382个逻辑读,运行时间近800毫秒。  查询优化器在查询计划里引入了筛选器(Filter)运算符,它进行逐行比较用来检查符合的行(ProductID < @i)  因为ORDER BY CarrierTrackingNumber,在执行计划里一个排序(Sort)运算符被引入。  排序运算符蔓延到了TempDb,因为不正确的基数计算(Cardinality Estimation)。用了带了本地变量与不等于谓语的组合,SQL Server从表的基数硬码估计30%的行。在我们的情况里估计行数是36395(121317 * 30%)。实际上查询返回120621行,这意味这排序(Sort)运算符必须蔓延到TempDb,因为请求的内存授予太小了。

现在我问你——你能改善这个查询么?你的建议是什么?休息下,想个几分钟。不修改查询本身,你如何改善这个查询?

我们来调试查询!当然,我们要做索引相关的调整来改善。没有支持的非聚集索引,那只能是查询优化器唯一可以使用计划来运行我们的查询。但对这个指定查询,什么是好的非聚集索引呢?一般来说,我通过看搜索谓语来考虑可能的非聚集速印。在我们的例子里,搜索谓语如下:

WHERE ProductID < @i

我们请求在ProductID列过滤的行。因此我们想在那个列创建支持的非聚集索引。我们建立索引:

CREATE NONCLUSTERED INDEX idx_Test ON Sales.SalesOrderDetail(ProductID) GO

在非聚集索引创建后,我们需要验证下改变,因此我们再次执行刚才的查询代码。结果如何捏?查询优化器并没有使用我们刚创建的非聚集索引!我们在搜索谓语上创建了支持的非聚集索引,查询优化器没有引用它?通常人们对此就无辙了。其实我们可以提示查询优化器来使用非聚集索引,来更好的理解“为什么”查询优化器没有自动选择索引:

 DECLARE @i INT = 999  SELECT  SalesOrderID,   SalesOrderDetailID,  CarrierTrackingNumber,   OrderQty,   LineTotalFROM Sales.SalesOrderDetail WITH (INDEX(idx_Test))WHERE ProductID < @i ORDER BY CarrierTrackingNumber GO

当你现在看执行计划时,你会看到下列的野性——一个并行计划:

查询花费了370109个逻辑读!运行时间基本和刚才的一样。这里到底发生了什么?当你仔细看执行计划,你会发现查询优化器引入了书签查找,因为刚才创建的非聚集索引,对于查询来说,不是一个覆盖非聚集索引。查询越过了所谓的临界点(Tipping Point),因为我们用当前的搜索谓语来获得几乎所有行。因此用非聚集索引和书签查找来组合没有意义。

不去想为什么查询优化器不选择刚才创建的非聚集索引,我们已经把自己的思路表达给了查询优化器本身,通过查询提示进行了询问了查询优化器,为什么非聚集索引没被自动选择。如我刚开始说的:我不想考虑太多。

使用非聚集索引解决这个问题,在非聚集索引的叶子层,我们必须对从SELECT列表的请求的额外列进行包含。你可以再次看下书签查找来看下在叶子层哪些列当前丢失:

CarrierTrackingNumber  OrderQty  UnitPrice  UnitDiscountPrice

我们重建那个非聚集索引:

CREATE NONCLUSTERED INDEX idx_Test ON Sales.SalesOrderDetail(ProductID)INCLUDE (CarrierTrackingNumber, OrderQty, UnitPrice, UnitPriceDiscount) WITH( DROP_EXISTING = ON )GO

我们已经做出了另1个改变,因此我们可以重新运行了查询来验证下。但是这次我们不加查询提示,因为现在查询优化器会自动选择非聚集索引。结果如何捏?当你看执行计划时,索引现在已被选择。

SQL Server现在在非聚集索引上进行了查找操作,但在执行计划里我们还有排序(Sort)运算符。因为基数计算30%的硬编码,排序(Sort)还是要蔓延到TempDb。偶滴神!我们的逻辑读已经降到了757,但运行时间还是近800毫秒。你现在应该怎么做?

现在我们可以尝试在非聚集索引的导航结构直接包含CarrierTrackingNumber列。这是SQL Server进行排序运算符的列。当我们在非聚集索引直接加了这列(作为主键),我们就物理排序了那列,因此排序(Sort)运算符应该会消失。作为积极的副作用,也不会蔓延到TempDb。在执行计划里,现在也没有运算符关心错误的基数计算。因此我们尝试那个假设,再次重建非聚集索引:

 CREATE NONCLUSTERED INDEX idx_Test ON Sales.SalesOrderDetail(CarrierTrackingNumber, ProductID)INCLUDE (OrderQty, UnitPrice, UnitPriceDiscount) WITH(   DROP_EXISTING = ON )GO

从索引定义可以看到,现在我们已经对CarrierTrackingNumber和ProductID列的数据物理预排序。当你再次重新执行查询,在你查看执行计划时,你会看到排序(Sort)运算符已经消失,SQL Server扫描了非聚集索引的整个叶子层(使用剩余谓语(residual predicate)作为搜索谓语)。

这个执行计划并不坏!我们只需要763个逻辑读,现在的运行时间已经降至600毫秒。和刚才的相比已经有25%的改善!但是:查询优化器建议我们一个更好的非聚集索引,通过缺少索引建议(Missing Index Recommendations)!暂且相信下,我们创建建议的非聚集索引:

CREATE NONCLUSTERED INDEX [SQL Server doesn't care about names, why I should care about names?]ON [Sales].[SalesOrderDetail] ([ProductID])INCLUDE ([SalesOrderID],[SalesOrderDetailID],[CarrierTrackingNumber],[OrderQty],[LineTotal])GO

当你现在重新执行最初的查询,你会发现令人惊讶的事情:查询优化器使用“我们”刚才创建的非聚集索引,缺少索引建议已经消失!

你刚刚创建了SQL Server从不使用的索引——除了INSERT,UPDATE和DELETE语句,SQL Server都要去维护你的非聚集索引。对于你的数据库,你刚创建了“单纯”浪费空间的索引。当另一方面,你已经通过消除丢失索引建议,满足了查询优化器。但这不是目的:目的是创建会被再次使用的索引。

结论:永不相信查询优化器!

上述就是小编为大家分享的如何调优SQL Server查询了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注编程网数据库频道。

您可能感兴趣的文档:

--结束END--

本文标题: 如何调优SQL Server查询

本文链接: https://www.lsjlt.com/news/69008.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何调优SQL Server查询
    这期内容当中小编将会给大家带来有关如何调优SQL Server查询,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。在今天的文章里,我想给你展示下,当你想对特定查询创建索引设...
    99+
    2022-10-19
  • SQL Server索引优化常用查询
    1.1、查找缺失索引 SELECT A.USER_SEEKS 查找次数,A.USER_SCANS 扫描次数, ROUND(A.AVG_TOTAL_USER_COST,2) 减少的用户查询的平均成本,A.AVG_USER_...
    99+
    2014-10-16
    SQL Server索引优化常用查询
  • Windows server 2016——SQL server T-SQL查询语句
    作者简介:一名云计算网络运维人员、每天分享网络与运维的技术与干货。  公众号:网络豆  座右铭:低头赶路,敬事如仪 个人主页: 网络豆的主页​​​​​ 目录 写在前面 介绍 一.SQL简介 1.SQL和T-SQL 2.T...
    99+
    2023-09-07
    sql php 数据库 原力计划
  • SQL Server中怎么优化多表查询
    这期内容当中小编将会给大家带来有关SQL Server中怎么优化多表查询,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1.执行路径ORACLE的这个功能大大地提高了SQL...
    99+
    2022-10-18
  • SQL Server中怎么优化查询速度
    这期内容当中小编将会给大家带来有关SQL Server中怎么优化查询速度,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。  优化SQLServer查询速度的方法有哪些  1...
    99+
    2022-10-18
  • sql server的权限查询
    --有关数据库的权限查询: WITH tree_roles as ( SELECT role_principal_id, member_principal_id FROM sys.databas...
    99+
    2022-10-18
  • SQL Server查询优化中的两个选项
    本文中,我们将介绍两个SQL Server中的可用概念,它们是使用SQL Server时值得注意的技术。 1.       &nbs...
    99+
    2022-10-18
  • 如何优化SQL查询
    本篇文章给大家分享的是有关如何优化SQL查询,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。我们致力于打造能够较好运行并延续较长一段时间的que...
    99+
    2022-10-19
  • 如何快速入门SQL Server XML查询
    本篇文章给大家分享的是有关如何快速入门SQL Server XML查询,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。sql xml 入门: -...
    99+
    2022-10-18
  • SQL Server中如何使用查询语句
    这期内容当中小编将会给大家带来有关SQL Server中如何使用查询语句,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一.查询第二个字母是t或者a的雇员的全部信息复制代码...
    99+
    2022-10-18
  • SQL server 系统视图查询
    -- 查询所有表名、字段名、类型、长度 select o.name, c.name,t.name,c.length from syscolumns c inner join systypes t on c.xtype= t.xt...
    99+
    2015-09-24
    SQL server 系统视图查询
  • SQL Server性能相关查询
      1、查询SQL Server执行过的SQL语句(执行次数) 有的时候,需要知道近段时间SQLSERVER执行了什么语句,可以用下面的方法: SELECT ss.SUM_execution_count , t.text , ss....
    99+
    2015-04-03
    SQL Server性能相关查询 数据库入门 数据库基础教程 数据库 mysql
  • SQL SERVER 跨服务器查询
    exec sp_addlinkedserver   '别名', '', 'SQLOLEDB','服务器地址'exec sp_addlinkedsrvlogin '别名','false',...
    99+
    2022-10-18
  • SQL Server的子查询详解
    目录一、子查询基础知识二、子查询规则三、限定子查询中的列名四、子查询的多层嵌套五、相关子查询六、子查询类型总结一、子查询基础知识 子查询是嵌套在SELECT、INSERT、UPDATE、DELETE语句中或另一个...
    99+
    2023-04-12
    SQL Server子查询语句 SQL Server子查询
  • SQL Server高级进阶之索引优化查询
    1.1、查找缺失索引 SELECT A.USER_SEEKS 查找次数,A.USER_SCANS 扫描次数, ROUND(A.AVG_TOTAL_USER_COST,2) 减少的用户查询的平均成本,A.AVG_USER_...
    99+
    2014-08-11
    SQL Server高级进阶之索引优化查询
  • 浅谈 SQL Server 查询优化与事务处理
    之前我们简单了解了各种查询的用法,然而在实际开发中还会用到一些比较高级的数据处理和查询,包括索引、视图、存储过程和触发器。从而能够更好地实现对数据库的操作、诊断及优化。 什么是索引呢,索引是 SQL Ser...
    99+
    2022-10-18
  • SQL Server一次SQL调优案例
    环境:Microsoft SQL Server 2016 (SP2-CU3)企业版 问题SQL: select  RowNumber = ROW_NUMBER()...
    99+
    2022-10-18
  • SQL Server如何实现全文搜索查询
    本篇内容介绍了“SQL Server如何实现全文搜索查询”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、概述全文索引在表中包括一...
    99+
    2023-07-05
  • 如何调优 Oracle SQL系列文章:查询优化器介绍
    如何调优 Oracle SQL系列文章 第四篇: 查询优化器概念之查询优化器介绍 。 4 查询优化器概念 本章描述了与查询优化器相关的最重要的概念,及其主要组件。 4....
    99+
    2022-10-18
  • SQL Server 跨库/服务器查询
    这里写目录标题 1 SQL Server 跨库/服务器查询1.1 跨库查询1.2 跨服务器查询1.2.1 创建链接服务器1.2.2 跨库查询 1.3 拓展:SQL Server 中所有权...
    99+
    2023-10-20
    服务器 sqlserver
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作