Sql-Server

SELECT 查詢和 SQL Server 緩衝區記憶體中的列計數

  • August 15, 2017

假設我有一個包含 30-50 百萬條記錄的表。它有大約 40 列。目前,當我請求數據時,它總是請求所有列,因為我們使用的是舊版 ORM。

我知道如果我們在SELECT查詢中指定更少的結果列,那麼 SQL Server 會更容易,因為它不需要從磁碟載入它們並返回到客戶端。但是 SQL Server 緩衝區記憶體呢?

假設我的應用程序執行這樣的查詢:

SELECT Column1,Column2,...,Column40
FROM ...
WHERE OwnerID = 42

因此它將載入這些記錄的所有列,將它們記憶體在記憶體中,然後返回給客戶端。

之後的下一個查詢將是

SELECT Column1,Column2
FROM ...
WHERE OwnerID = 42

所以它不會載入其他列並返回更少的數據,但無論如何它們是從記憶體而不是從磁碟載入的,因為我們在之前的查詢中載入了所有列。它會幫助 SQL Server 還是因為 SQL 記憶體而根本不重要?SQL Server 的複雜性會有多大差異?

我現在無法刪除第一個查詢,所以我正在嘗試優化同一實體的下一個查詢並試圖找出一個好方法。

謝謝!

SQL Server 將一行的所有列一起儲存在一個磁碟頁中。(它比這更複雜,但對於int等等char。這或多或少是真的。)為了檢索任何列的值,整個頁面被讀入 RAM。因此,一旦您擁有可用於給定行的任何列,該行的所有列都可用。

響應查詢涉及多個緩衝區/記憶體。一個是大頁面緩衝池,其中從磁碟讀取的頁面保存在記憶體中,因此執行計劃可以對它們進行操作。是的,如果一個查詢導致一個頁面被載入到緩衝池中,那麼所有後續查詢都將使用緩衝池中的同一頁面,而不必承受 IO 成本。然而,這是一個偶然的性能提升,不應依賴它,因為 SQL Server 可能會在需要空間的任何時候選擇從緩衝池中逐出任何頁面。

當查詢的輸出通過連接發送應用程序**時,會發生另一組緩衝。這(主要)是基於每個連接的,因此複製工作會複製所需的資源(或多或少)。

另一個成本是您在返回所有列時錯過的優化。覆蓋索引和“INCLUDES”列是沒有意義的。每次讀取都必須檢索底層聚集索引(或堆)頁面。可以肯定的是,SQL Server 不會使用它可能選擇的特定索引,因為掃描集群計劃比索引和集群計劃便宜。

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