Sql-Server

不相關的列會影響 select 語句的查詢時間嗎?

  • October 5, 2017

我只是好奇。

假設您有一個包含 100 萬條記錄/行的表。

select order_value from store.orders

在實際查詢時間中,該表是否有 1 個欄位、2 個欄位或 100 個欄位有區別嗎?我的意思是“order_value”以外的所有欄位。

現在我正在將數據推送到數據倉庫。有時我將欄位轉儲到“可能在未來某天使用”的表中 - 但現在它們不會被任何東西查詢。這些“無關”欄位是否會直接或間接影響不包含它們的選擇語句(不是*我的意思)?

這實際上取決於索引和數據類型。

以 Stack Overflow 數據庫為例,Users 表如下所示:

堅果

它在 Id 列上有一個 PK/CX。所以它是按 Id 排序的整個表數據。

以它作為唯一的索引,如果它不存在的話,SQL 必須將整個東西(沒有 LOB 列)讀入記憶體。

DBCC DROPCLEANBUFFERS-- Don't run this anywhere near prod.

SET STATISTICS TIME, IO ON 

SELECT u.Id
INTO  #crap1
FROM dbo.Users AS u

統計時間和 io 配置文件如下所示:

Table 'Users'. Scan count 7, logical reads 80846, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:
  CPU time = 2406 ms,  elapsed time = 446 ms.

如果我只在 Id 上添加一個額外的非聚集索引

CREATE INDEX ix_whatever ON dbo.Users (Id)

我現在有一個小得多的索引來滿足我的查詢。

DBCC DROPCLEANBUFFERS-- Don't run this anywhere near prod.

SELECT u.Id
INTO  #crap2
FROM dbo.Users AS u

這裡的簡介:

Table 'Users'. Scan count 7, logical reads 6587, physical reads 0, read-ahead reads 6549, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:
  CPU time = 2344 ms,  elapsed time = 384 ms.

我們能夠進行更少的讀取並節省一點 CPU 時間。

如果沒有有關您的表定義的更多資訊,我無法真正嘗試更好地重現您嘗試測量的內容。

但是你是說除非在那個單獨的列上有一個特定的索引,否則其他列/欄位也會被掃描?這只是行儲存表設計固有的缺點嗎?為什麼會掃描不相關的欄位?

是的,這是特定於行儲存表的。數據按數據頁上的行儲存。即使頁面上的其他數據與您的查詢無關,也需要將整行>頁面>索引讀入記憶體。我不會說其他列被“掃描”得如此之多,因為它們存在​​的頁面被掃描以檢索與查詢相關的單個值。

使用舊電話簿範例:即使您只是在閱讀電話號碼,當您翻頁時,您也會將姓氏、名字、地址等連同電話號碼一起翻閱。

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