これは実際にはインデックスとデータ型に依存します。
例として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時間を少し節約できます。
テーブルの定義に関する詳細情報がないと、測定しようとしているものをより適切に再現することはできません。
しかし、その唯一の列に特定のインデックスがない限り、他の列/フィールドもスキャンされると言っていますか?これは、行ストアテーブルの設計に固有の欠点ですか?無関係なフィールドがスキャンされるのはなぜですか?
はい、これは行ストアテーブルに固有です。データは、データページの行ごとに格納されます。ページ上の他のデータがクエリに関係ない場合でも、行全体>ページ>インデックスをメモリに読み込む必要があります。他の列が「スキャン」されているとは言いませんが、それらの列が存在するページがスキャンされ、クエリに関連するそれらの単一の値を取得します。
古い電話帳の例を使用すると、電話番号を読んでいるだけの場合でも、ページをめくると、姓、名、住所などが電話番号とともに表示されます。