Sql-Server

如何提高 MS SQL Server 中原始查詢的性能?

  • May 19, 2012

我有 ASP.NET 網站,它自己獨立記憶體數據,並且數據長時間不會更改,因此不需要使用相同的查詢第二次查詢 SQL Server。我需要提高轉到該 SQL Server 的首次(原始)查詢的性能。某些查詢處理的數據太多,以至於它們可能會導致 SQL Server 使用tempdb。我不使用臨時表變數或臨時表,因此 SQL Server 決定在tempdb需要時自行使用。

我的數據庫大小是 16Gb,我的伺服器機器上有 32Gb 的物理 RAM 可用。

我了解 MS SQL Server 記憶體策略會嘗試將數據保存在 RAM 中,以便在需要再次載入相同數據時加快類似查詢的性能。除此之外,它會嘗試使用可用的 RAM 而不是 tempdb 來加速性能,而不會導致磁碟訪問。

我想當需要在 tempdb SQL Server 中儲存某些內容的查詢出現並且沒有足夠的可用 RAM 時,SQL Server 有 2 個選擇:

1)解除安裝一些記憶體數據並使用備用RAM而不是tempdb來避免磁碟寫入

  1. 為將來的查詢保留記憶體數據並開始使用 tempdb,這會導致寫入慢速磁碟。

我不知道 SQL Server 在這種情況下會做出什麼選擇,但我希望它做出選擇 #1,因為我只關心首次(處女)查詢的性能,因為我再也不會向 SQL Server 發送相同的查詢(儘管我可能會發送類似的查詢)。

這種情況下的 SQL Server 記憶體策略是什麼?

它如何在避免使用 tempdb 進行原始查詢和第二次查詢的速度之間平衡 RAM 的使用?

是否可以配置 SQL Server 以使其做出選擇 #1 ?如果是,那怎麼辦?

我還能如何提高所有原始 SQL 查詢的性能?

由於我不了解 SQL Server 記憶體策略,因此我想將數據庫放在 RAM Disk 上。這將確保任何原始查詢都可以高速載入未記憶體的數據,即使 SQL Server 總是選擇 #1。這樣做的風險是,如果 SQL Server 繼續選擇 #2,它可能會開始使用更多的 tempdb 和更少的可用 RAM(在我使用 16Gb 作為 RAM 磁碟後只剩下 16Gb),這將減慢那些導致溢出到tempdb.

我對 SQL 2008 R2 的解決方案感興趣,但我猜它可能與 SQL 2008、SQL 2005 相同,並且可能是 SQL 2000。

說明:

該盒子上沒有執行其他應用程序,它專用於 SQL Server。網站在單獨的盒子上執行。

它是 Windows Server 2008 R2 Enterprise 64 位上的 SQL Server 2008 R2 標準版 64 位。

我只執行只讀查詢,並且數據庫設置為只讀

讓我們假設已經有好的索引。這個問題是關於 SQL Server 做出選擇 #1 與選擇 #2,它是如何做到的,是否有控制它的方法以及 RAM Disk 是否幫助它為原始查詢做出正確的選擇。

您的問題基本上可以改寫為“查詢記憶體授予如何工作?”。有關該主題的好讀物是理解 SQL 伺服器記憶體授予。在查詢開始執行之前,它可能需要為排序和散列以及其他需要記憶體的操作授予記憶體。此記憶體授予是一個估計值。根據目前系統狀態(正在執行和待處理的請求數、可用記憶體等),系統向查詢授予最多所需數量的記憶體授予。授予記憶體後,查詢開始執行(它可能必須在可怕的“資源信號量”隊列中等待才能獲得授權)。在執行時,它保證了記憶體授予由系統。這個記憶體量可以與數據頁共享(因為它們總是可以刷新到磁碟),但不能與其他記憶體使用共享(即它不能被“竊取”)。因此,當查詢開始從其授權中請求已送出的記憶體時,引擎將部署您所謂的“策略#1”:數據頁可能會被驅逐(如果髒了則刷新),以便為查詢提供它所承諾的記憶體。現在,如果估計是正確的並且授予是請求記憶體的 100%,則查詢不應“溢出”。但是,如果估計不正確(歸結為基數估計,因此受到陳舊統計數據的影響),或者如果查詢沒有獲得它所要求的全部授權,則查詢將“溢出”。這是 tempdb 出現的時候,性能通常會下降。

在此過程中,您可以使用的唯一控制某些東西的旋鈕是資源調控器。由於 RG 可用於為池指定MIN設置,因此它可用於為特定工作負載保留記憶體,以便它實際獲得它請求的記憶體授權。當然,在您進行了適當的調查之後,表明減少的記憶體授予罪魁禍首,當然,在評估了對其他工作負載的影響之後。並且經過測試,當然。

現在讓我們回到你原來的問題。如果你的調查是正確的(一個很大的如果)我想指出兩個問題:

  • 您在需要為網站授予記憶體的生產查詢中執行。這是一個很大的禁忌。記憶體授予表示在服務 HTTP 請求中沒有位置的分析查詢。
  • 您的查詢可能不是獲得他們請求的記憶體授權的事件。同樣,對於像網站這樣的延遲關鍵型工作負載來說,更是禁忌。

所以這告訴我你有一個基本的設計和架構問題。網站是延遲驅動的,應該創建類似 OLTP 的工作負載,沒有記憶體授予,也沒有對查詢的記憶體壓力。更不用說沒有溢出。分析查詢應該在離線作業中執行並儲存預處理結果,以便在 HTTP 請求需要它們時快速可用。

引用自:https://dba.stackexchange.com/questions/18164