看懂SqlServer查询计划 SQL语句优化分析

对于SQL Server的优化来说,优化查询可能是很常见的事情。由于数据库的优化,本身也是一个涉及面比较的广的话题, 因此本文只谈优化查询时如何看懂SQL Server查询计划。毕竟我对SQL Server的认识有限,如有错误,也恳请您在发现后及时批评指正。

首先,打开【SQL Server Management Studio】,输入一个查询语句看看SQL Server是如何显示查询计划的吧。
说明:本文所演示的数据库,是我为一个演示程序专用准备的数据库, 可以在此网页中下载。

select v.OrderID, v.CustomerID, v.CustomerName, v.OrderDate, v.SumMoney, v.Finished
from   OrdersView as v
where v.OrderDate >= '2010-12-1' and v.OrderDate < '2011-12-1';

其中,OrdersView是一个视图,其定义如下:

SELECT     dbo.Orders.OrderID, dbo.Orders.CustomerID, dbo.Orders.OrderDate, 
            dbo.Orders.SumMoney, dbo.Orders.Finished, 
            ISNULL(dbo.Customers.CustomerName, N'') AS CustomerName
FROM         dbo.Orders LEFT OUTER JOIN
                dbo.Customers ON dbo.Orders.CustomerID = dbo.Customers.CustomerID

对于前一句查询,SQL Server给出的查询计划如下(点击工具栏上的【显示估计的执行计划】按钮):

显示执行计划的快捷键是:CTRL+L

或者在“查询”菜单上选中“包括实际的查询计划”

从这个图中,我们至少可以得到3个有用的信息:
1. 哪些执行步骤花费的成本比较高。显然,最右边的二个步骤的成本是比较高的。
2. 哪些执行步骤产生的数据量比较多。对于每个步骤所产生的数据量, SQL Server的执行计划是用【线条粗细】来表示的,因此也很容易地从分辨出来。
3. 每一步执行了什么样的动作。

对于一个比较慢的查询来说,我们通常要知道哪些步骤的成本比较高,进而,可以尝试一些改进的方法。 一般来说,如果您不能通过:提高硬件性能或者调整OS,SQL Server的设置之类的方式来解决问题,那么剩下的可选方法通常也只有以下这些了:
1. 为【scan】这类操作增加相应字段的索引。
2. 有时重建索引或许也是有效的,具体情形请参考后文。
3. 调整语句结构,引导SQL Server采用其它的查询方案去执行。
4. 调整表结构(分表或者分区)。

下面再来说说一些很重要的理论知识,这些内容对于执行计划的理解是很有帮助的。

SQL Server 查找记录的方法

说到这里,不得不说SQL Server的索引了。SQL Server有二种索引:聚集索引和非聚集索引。二者的差别在于:【聚集索引】直接决定了记录的存放位置, 或者说:根据聚集索引可以直接获取到记录。【非聚集索引】保存了二个信息:1.相应索引字段的值,2.记录对应聚集索引的位置(如果表没有聚集索引则保存记录指针)。 因此,如果能通过【聚集索引】来查找记录,显然也是最快的。

SQL Server 会有以下方法来查找您需要的数据记录:
1. 【Table Scan】:遍历整个表,查找所有匹配的记录行。这个操作将会一行一行的检查,当然,效率也是最差的。
2. 【Index Scan】:根据索引,从表中过滤出来一部分记录,再查找所有匹配的记录行,显然比第一种方式的查找范围要小,因此比【Table Scan】要快。
3. 【Index Seek】:根据索引,定位(获取)记录的存放位置,然后取得记录,因此,比起前二种方式会更快。
4. 【Clustered Index Scan】:和【Table Scan】一样。注意:不要以为这里有个Index,就认为不一样了。 其实它的意思是说:按聚集索引来逐行扫描每一行记录,因为记录就是按聚集索引来顺序存放的。 而【Table Scan】只是说:要扫描的表没有聚集索引而已,因此这二个操作本质上也是一样的。
5. 【Clustered Index Seek】:直接根据聚集索引获取记录,最快!

所以,当发现某个查询比较慢时,可以首先检查哪些操作的成本比较高,再看看那些操作在查找记录时, 是不是【Table Scan】或者【Clustered Index Scan】,如果确实和这二种操作类型有关,则要考虑增加索引来解决了。 不过,增加索引后,也会影响数据表的修改动作,因为修改数据表时,要更新相应字段的索引。所以索引过多,也会影响性能。 还有一种情况是不适合增加索引的:某个字段用0或1表示的状态。例如可能有绝大多数是1,那么此时加索引根本就没有意义。 这时只能考虑为0或者1这二种情况分开来保存了,分表或者分区都是不错的选择。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值