Sql-Server
不相關的列會影響 select 語句的查詢時間嗎?
我只是好奇。
假設您有一個包含 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 時間。
如果沒有有關您的表定義的更多資訊,我無法真正嘗試更好地重現您嘗試測量的內容。
但是你是說除非在那個單獨的列上有一個特定的索引,否則其他列/欄位也會被掃描?這只是行儲存表設計固有的缺點嗎?為什麼會掃描不相關的欄位?
是的,這是特定於行儲存表的。數據按數據頁上的行儲存。即使頁面上的其他數據與您的查詢無關,也需要將整行>頁面>索引讀入記憶體。我不會說其他列被“掃描”得如此之多,因為它們存在的頁面被掃描以檢索與查詢相關的單個值。
使用舊電話簿範例:即使您只是在閱讀電話號碼,當您翻頁時,您也會將姓氏、名字、地址等連同電話號碼一起翻閱。