簡體   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