如何提高查询性能

时间:2011-07-29 16:31:08

标签: sql sql-server sql-server-2008

我在表格中有很多记录。当我执行以下查询时,需要花费很多时间。如何提高性能?

SET ROWCOUNT 10
SELECT StxnID
      ,Sprovider.description as SProvider
      ,txnID
      ,Request
      ,Raw
      ,Status
      ,txnBal
      ,Stxn.CreatedBy
      ,Stxn.CreatedOn
      ,Stxn.ModifiedBy
      ,Stxn.ModifiedOn
      ,Stxn.isDeleted
  FROM Stxn,Sprovider
  WHERE Stxn.SproviderID = SProvider.Sproviderid
  AND Stxn.SProviderid = ISNULL(@pSProviderID,Stxn.SProviderid)
  AND Stxn.status = ISNULL(@pStatus,Stxn.status)
  AND Stxn.CreatedOn BETWEEN ISNULL(@pStartDate,getdate()-1) and  ISNULL(@pEndDate,getdate())
  AND Stxn.CreatedBy = ISNULL(@pSellerId,Stxn.CreatedBy)  
  ORDER BY StxnID DESC

stxn表有超过100,000条记录。

查询是从asp.net c#中的报表查看器运行的。

7 个答案:

答案 0 :(得分:4)

当我尝试进行具有多个搜索条件的搜索查询时,这是我的首选文章。

http://www.sommarskog.se/dyn-search-2008.html

您的查询的最大问题是column=ISNULL(@column, column)语法。 MSSQL不会使用索引。请考虑将其更改为(column = @column AND @column IS NOT NULL)

答案 1 :(得分:3)

您应该考虑使用执行计划并查找缺少的索引。此外,执行需要多长时间?什么对你来说很慢?

也许你也不能返回那么多行,但这只是猜测。实际上,我们需要查看您的表和索引以及执行计划。

检查sql-tuning-tutorial

答案 2 :(得分:3)

首先,使用SELECT TOP ()代替SET ROWCOUNT - 优化器将有更好的机会。另一个建议是使用正确的内连接,而不是使用旧样式表,表连接语法结束使用笛卡尔积(这不是这里的情况,但使用旧语法可以更容易)。应该是:

...
FROM Stxn INNER JOIN Sprovider
  ON Stxn.SproviderID = SProvider.Sproviderid
...

如果您认为100K行很多,或者说这个音量是缓慢的原因,那你就错了。很可能你的索引策略确实很差,可能是一些参数嗅探,可能是一些隐式转换......如果不了解数据类型,索引和查看计划,很难说清楚。

答案 3 :(得分:3)

有很多事情可能会影响查询的性能。虽然100k的记录真的不是那么多。

要考虑的项目(无特定顺序)

硬件:

  1. SQL Server内存是否受限制?换句话说,它有足够的RAM来完成它的工作吗?如果将内存交换到磁盘,则表明您需要升级。
  2. 机器磁盘是否受限制。换句话说,驱动器是否足够快以跟上您需要运行的查询?如果内存受限,那么磁盘速度就会变得更大。
  3. 机器处理器是否受限制?例如,当您执行查询时,处理器是否会长时间飙升?或者,是否已经有许多其他查询正在运行,这些查询正在从您的资源中获取资源......
  4. 数据库结构:

    1. 您对where子句中使用的列有索引吗?如果表没有索引,则必须对两个表进行完全扫描以确定哪些记录匹配。
    2. 消除ISNULL函数调用。如果这是直接查询,请让调用代码验证参数并在执行前设置默认值。如果它在存储过程中,请执行s'proc顶部的检查。除非您使用执行参数嗅探的RECOMPILE执行此操作,否则必须为每一行评估这些函数。
    3. 网络

      1. 您和服务器之间的网络速度是否较慢?根据提取的数据量,您可以通过线路提取GB的数据。我不确定“raw”列中存储了什么。你需要问的第一个问题是“有多少数据会回到客户端?”例如,如果每个记录的大小为1MB +,那么您可能会遇到磁盘和网络限制。
      2. 常规

        1. 我不确定你的问题中“慢”的意思。是否意味着查询需要大约1秒才能处理,或者是否意味着需要5分钟?这里的一切都是相对的。
        2. 基本上,如果没有你提出的很多问题,就不可能给出一个难以回答的答案。如果您分析查询,了解返回客户端的内容和数量,并观察各个部分之间的交互,所有这些都将证明。

          最后,根据返回客户端的数据量,可能无法提高硬件更改的性能。

答案 4 :(得分:0)

确保Stxn.SproviderID,Stxn.status,Stxn.CreatedOn,Stxn.CreatedBy,Stxn.StxnID和SProvider.Sproviderid都定义了索引。

(注意 - 你可能不需要所有,但它不会受到伤害。)

答案 5 :(得分:0)

我没有看到可以对查询本身做多少,但我可以看到在架构上完成的事情:

  • 在Stxn.SproviderID上创建索引/ PK
  • 在SProvider.Sproviderid上创建索引/ PK
  • 在状态,CreatedOn,CreatedBy,StxnID
  • 上创建索引

答案 6 :(得分:0)

需要考虑的事项:当ROWCOUNT或TOP与ORDER BY子句一起使用时,首先创建并排序整个结果集,然后返回前10个结果。

如果没有Order By子句,它如何运行?