中成网站建设
    成都做网站,就选中成网站建设!专业四川网站建设,成都网站建设服务提供商
            企业宣传网站建设、电子商务网站建设、OA办公系统。联系电话:028-66165255

文章详情

mssql 如何优化访问速度?(6)

  分析索引

  首先,Tom想到了审查这个存储过程使用到的表的索引,很快他发现下面两列的索引无故丢失了:

  OrderDetails.ProductID

  OrderDetails.SalesOrderID

  他在这两个列上创建了非聚集索引,然后再执行存储过程:

  exec uspGetSalesInfoForDateRange ‘1/1/2009’, 31/12/2009 with recompile

  性能有所改变,但仍然低于预期(这次花了35秒),注意这里的with recompile子句告诉SQL Server引擎重新编译存储过程,重新生成执行计划,以利用新创建的索引。

  分析查询执行计划

  Tom接下来查看了SQL Server Management Studio中的执行计划,通过分析,他找到了某些重要的线索:

  1、发生了一次表扫描,即使该表已经正确设置了索引,而表扫描占据了总体查询执行时间的30%;

  2、发生了一个嵌套循环连接。

  Tom想知道是否有索引碎片,因为所有索引配置都是正确的,通过TSQL他知道了有两个索引都产生了碎片,很快他重组了这两个索引,于是表扫描消失了,现在执行存储过程的时间减少到25秒了。

  为了消除嵌套循环连接,他又在表上创建了覆盖索引,时间进一步减少到23秒。

  实施最佳实践

  Tom发现有个UDF有问题,代码如下: 

ALTER FUNCTION [dbo].[ufnGetLineTotal]

  (

  
@SalesOrderDetailID int

  )

  
RETURNS money

  AS

  BEGIN

  DECLARE @CurrentProductRate money

  DECLARE @CurrentDiscount money

  DECLARE @Qty int

  SELECT

  @CurrentProductRate = ProductRates.CurrentProductRate,

  
@CurrentDiscount = ProductRates.CurrentDiscount,

  
@Qty = OrderQty

  
FROM

  ProductRates INNER JOIN OrderDetails ON

  OrderDetails.ProductID = ProductRates.ProductID

  
WHERE

  OrderDetails.SalesOrderDetailID = @SalesOrderDetailID

  RETURN (@CurrentProductRate-@CurrentDiscount)*@Qty

  END

  在计算订单总金额时看起来代码很程序化,Tom决定在UDF的SQL中使用内联SQL。

  dbo.ufnGetLineTotal(SalesOrderDetailID) Total -- 旧代码

  (CurrentProductRate-CurrentDiscount)*OrderQty Total -- 新代码

  执行时间一下子减少到14秒了。

  在select查询清单中放弃不必要的Text列

  为了进一步提升性能,Tom决定检查一下select查询清单中使用的列,很快他发现有一个Products.DetailedDescription列是Text类型,通过对应用程序代码的走查,Tom发现其实这一列的数据并不会立即用到,于是他将这一列从select查询清单中取消掉,时间一下子从14秒减少到6秒,于是Tom决定使用一个存储过程应用延迟加载策略加载这个Text列。

  最后Tom还是不死心,认为6秒也无法接受,于是他再次仔细检查了SQL代码,他发现了一个like子句,经过反复研究他认为这个like搜索完全可以用全文搜索替换,最后他用全文搜索替换了like搜索,时间一下子降低到1秒,至此Tom认为调优应该暂时结束了。

  小结

  看起来我们介绍了好多种优化数据访问的技巧,但大家要知道优化数据访问是一个无止境的过程,同样大家要相信一个信念,无论你的系统多么庞大,多么复杂,只要灵活运用我们所介绍的这些技巧,你一样可以驯服它们。下一篇将介绍高级索引和反范式化。


 


上一篇:最佳数据仓库体系--Hadoop

下一篇:已经是最后一篇