簡體   English   中英

優化存儲過程

[英]Optimizing a Stored Procedure

我有一個龐大的查詢,一直在正常工作,但是由於數據庫中現在有大量記錄或記錄,因此存儲過程完成所需的查詢時間越來越長。

我花了很長時間讓查詢開始工作,但我對A)簡化查詢或B)將其分解為較小的查詢/存儲過程並不自信。

有專家可以幫我嗎?

 SELECT r.resourceFirstName, r.resourceLastName, a.eventDateTime, CONVERT(char(1), a.eventType) as eventType, CONVERT(varchar(5), a.reasonCode) as reasonCode, r.extension, GETDATE() AS ciscoDate into #temp_Agent FROM CCX1.db_cra.dbo.Resource r INNER JOIN CCX1.db_cra.dbo.AgentStateDetail a ON r.resourceID = a.agentID INNER JOIN ( SELECT p.resourceFirstName, p.resourceLastName, MAX(e.eventDateTime) MaxeventDateTime FROM CCX1.db_cra.dbo.Resource p INNER JOIN CCX1.db_cra.dbo.AgentStateDetail e ON p.resourceID = e.agentID where e.eventDateTime > (GETDATE() - 1) GROUP BY p.resourceFirstName, p.resourceLastName ) d ON r.resourceFirstName = d.resourceFirstName AND r.resourceLastName = d.resourceLastName AND a.eventDateTime = d.MaxeventDateTime AND r.active = 1 where a.eventDateTime >= (GETDATE() - 7) ORDER BY r.resourceLastName, r.resourceFirstName ASC 

僅查詢無法給出正確答案。 但...

考慮在“ eventDateTime”上放置一個索引。

您似乎在1天內加入了一組記錄。 這將使外部查詢中的7天過濾條件變得無關緊要。 我沒有測試能力,但是也許您的查詢可以簡化為這個? (下面的偽代碼)

還考慮不同的解決方案。 也許根據日期時間對表進行分區。 也許有一個單獨的數據庫,用於使用星型模式或多維數據集設計進行報告。

臨時表#temp_Agent正在做什么?

declare @max datetime = (select max(eventDateTime) 
                         from CCX1.db_cra.dbo.AgentStateDetail 
                         where active=1 
                         and eventDateTime > getdate()-1);
if(@max is null)
    exit no records today

SELECT r.resourceFirstName, 
r.resourceLastName,
a.eventDateTime, 
CONVERT(char(1), a.eventType) as eventType, 
CONVERT(varchar(5), a.reasonCode) as reasonCode, 
r.extension, 
GETDATE() AS ciscoDate 

into #temp_Agent

FROM CCX1.db_cra.dbo.Resource r 
INNER JOIN CCX1.db_cra.dbo.AgentStateDetail a ON r.resourceID = a.agentID 

where r.active = 1 
and a.eventDateTime = @max;

如果沒有完整的表定義,很難對查詢為什么掛出進行故障排除,但是我為您提供了一些技巧,可以幫助您提高查詢的性能:

  1. 代替使用諸如“ #temp_Agent”之類的臨時表,最好創建“表”類型的局部變量。 您可以獲得完全相同的結果,但是可以大大提高性能,因為:

    • 可以使用主鍵和索引來創建“表”類型的局部變量,從而改善SQL查找信息的方式。

    • 可以對局部變量進行聚類,這也可以提高某些情況下的性能,因為信息是直接從磁盤訪問的

    • 臨時表要求SQL在運行時解析用於存儲查詢所獲得信息的列的類型。

  2. 如果您需要將信息存儲在臨時表,變量等中,請避免在這些變量中存儲不必要的信息。 例如,如果您僅在過程中需要后者兩個id列,則應避免包含多余的列以檢索泡沫

  3. 如果需要從多個源中檢索大量信息,則應考慮使用視圖,該視圖也可以建立索引並改善信息的檢索。

  4. 避免使用不必要的字符串排序,分組,轉換和連接。 這些特定的操作cad會嚴重降低QUery的性能。

另外,您可以使用旨在改善數據庫和對象的SQL Server工具:

  • 檢查查詢的執行計划(菜單查詢->包括實際執行計划,或按Control + M)
  • 運行SQL Server Engine Tunning Advisor來分析跟蹤文件(請參閱SQL Server Profiler)並添加額外的索引以提高數據庫性能
  • 與SQL Server Profiler一起檢查是否您的查詢沒有在用於獲​​取信息的表中生成死鎖。 在所有查詢中都使用“提示”是一種好習慣,以避免在某些情況下要避免的鎖定問題和其他行為。

Se附加鏈接可以更好地理解我的意思:

了解執行計划

提示的用法

SQL Server中可用的Tunning選項

希望這些信息對您有所幫助。

假設這是SQLServer,請嘗試:

WITH CTE AS
(SELECT r.resourceFirstName, 
        r.resourceLastName,
        a.eventDateTime, 
        CONVERT(char(1), a.eventType) as eventType, 
        CONVERT(varchar(5), a.reasonCode) as reasonCode, 
        r.extension, 
        GETDATE() AS ciscoDate,
        RANK() OVER (PARTITION BY r.resourceFirstName, r.resourceLastName
                     ORDER BY a.eventDateTime DESC) RN
 FROM CCX1.db_cra.dbo.Resource r 
 INNER JOIN CCX1.db_cra.dbo.AgentStateDetail a 
         ON r.resourceID = a.agentID AND a.eventDateTime >= (GETDATE() - 1) 
 where r.active = 1)
SELECT resourceFirstName, resourceLastName, eventDateTime, eventType, reasonCode, r.extension, ciscoDate
into #temp_Agent
FROM CTE
WHERE RN=1
ORDER BY r.resourceLastName, r.resourceFirstName ASC

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM