繁体   English   中英

如何提高查询性能

[英]How to improve query performance

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

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#中的报表查看器运行的。

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

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

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

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

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

检查sql-tuning-tutorial

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

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

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

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

要考虑的项目(没有特别的顺序)

硬件:

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

数据库结构:

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

网络:

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

一般:

  1. 我不确定你的问题中“慢”意味着什么。 是否意味着查询需要大约1秒才能处理,或者是否意味着需要5分钟? 这里的一切都是相对的。

基本上,如果没有你提出的很多问题,就不可能给出一个难以回答的答案。 如果您分析查询,了解返回客户端的内容和数量,并观察各个部分之间的交互,所有这些都将证明。

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

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM