ページの読み取りReading Pages

適用対象:Applies to: はいSQL ServerSQL Server (サポートされているすべてのバージョン) yesSQL ServerSQL Server (all supported versions) 適用対象:Applies to: はいSQL ServerSQL Server (サポートされているすべてのバージョン) yesSQL ServerSQL Server (all supported versions)

SQL Server データベース エンジンDatabase Engine のインスタンスからの I/O には、論理読み取りと物理読み取りがあります。The I/O from an instance of the SQL Server データベース エンジンDatabase Engine includes logical and physical reads. 論理読み取りは、 データベース エンジンDatabase Engineバッファー キャッシュからページを要求するたびに行われます。A logical read occurs every time the データベース エンジンDatabase Engine requests a page from the buffer cache. 要求したページがバッファー キャッシュに存在しない場合、物理読み取りが行われ、まず、ディスクからキャッシュにページがコピーされます。If the page is not currently in the buffer cache, a physical read first copies the page from disk into the cache.

データベース エンジンDatabase Engine のインスタンスによって生成された読み取り要求はリレーショナル エンジンによって制御され、ストレージ エンジンによって最適化されます。The read requests generated by an instance of the データベース エンジンDatabase Engine are controlled by the relational engine and optimized by the storage engine. リレーショナル エンジンは、最も効率的なアクセス方法 (テーブル スキャン、インデックス スキャン、キーによる読み取りなど) を判別します。アクセス方法とストレージ エンジンのバッファー マネージャー コンポーネントによって、実行される読み取りの一般的なパターンが決まり、そのアクセス方法の実装に必要な最適化がその読み取りに対して行われます。The relational engine determines the most effective access method (such as a table scan, an index scan, or a keyed read); the access methods and buffer manager components of the storage engine determine the general pattern of reads to perform, and optimize the reads required to implement the access method. バッチを実行するスレッドが、読み取りのスケジュールを設定します。The thread executing the batch schedules the reads.

先行読み取りRead-Ahead

データベース エンジンDatabase Engine では、先行読み取りと呼ばれるパフォーマンス最適化メカニズムがサポートされています。The データベース エンジンDatabase Engine supports a performance optimization mechanism called read-ahead. 先行読み取りでは、クエリ実行プランに必要なデータ ページとインデックス ページを予想し、実際にクエリで使用される前に、予想したページをバッファー キャッシュに配置します。Read-ahead anticipates the data and index pages needed to fulfill a query execution plan and brings the pages into the buffer cache before they are actually used by the query. これにより、計算と I/O を同時に行うことができ、CPU とディスクが最大限に活用されます。This allows computation and I/O to overlap, taking full advantage of both the CPU and the disk.

データベース エンジンDatabase Engine ではこの先行読み取りメカニズムにより、1 つのファイルから連続するページを最大 64 ページ (512 KB) まで読み取ることができます。The read-ahead mechanism allows the データベース エンジンDatabase Engine to read up to 64 contiguous pages (512KB) from one file. この読み取りは、バッファー キャッシュ内の (多くの場合連続していない) バッファーを適切な数まで読み取る、単一のスキャッター/ギャザー読み取り処理として実行されます。The read is performed as a single scatter-gather read to the appropriate number of (probably non-contiguous) buffers in the buffer cache. この範囲のいずれかのページが既にバッファー キャッシュに存在する場合、読み取りの完了時に、読み取られたページの中から対応するページが破棄されます。If any of the pages in the range are already present in the buffer cache, the corresponding page from the read will be discarded when the read completes. また、バッファー キャッシュのページと対応するページが複数存在する場合、それらのページが先頭または末尾からまとめて "切り捨て" られることもあります。The range of pages may also be "trimmed" from either end if the corresponding pages are already present in the cache.

先行読み取りの対象は、データ ページとインデックス ページの 2 種類です。There are two kinds of read-ahead: one for data pages and one for index pages.

データ ページの読み取りReading Data Pages

データ ページの読み取りに使用されるテーブル スキャンは、 データベース エンジンDatabase Engineでは非常に効率的に行われます。Table scans used to read data pages are very efficient in the データベース エンジンDatabase Engine. SQL Server データベース内の IAM (Index Allocation Map) ページには、テーブルまたはインデックスで使用されているエクステントの一覧が格納されています。The index allocation map (IAM) pages in a SQL Server database list the extents used by a table or index. ストレージ エンジンは IAM を読み取ることで、読み取る必要のあるディスク アドレスが並べ替えられたリストを構築できます。The storage engine can read the IAM to build a sorted list of the disk addresses that must be read. これによりストレージ エンジンは、ディスク上の位置に基づき、順番に行われる大量の順次読み取りとして、I/O を最適化できます。This allows the storage engine to optimize its I/Os as large sequential reads that are performed in sequence, based on their location on the disk. IAM ページの詳細については、「 オブジェクトに使用されている領域の管理」をご覧ください。For more information about IAM pages, see Managing Space Used by Objects.

インデックス ページの読み取りReading Index Pages

ストレージ エンジンは、インデックス ページをキー順で直列に読み取ります。The storage engine reads index pages serially in key order. 次の図は、キーのセットを格納しているリーフ ページのセットと、リーフ ページをマップしている中間インデックス ノードの例を示しています。For example, this illustration shows a simplified representation of a set of leaf pages that contains a set of keys and the intermediate index node mapping the leaf pages. インデックスのページ構造の詳細については、「 クラスタ化インデックスの構造」をご覧ください。For more information about the structure of pages in an index, see Clustered Index Structures.

Reading_Pages

ストレージ エンジンは、リーフ レベルの上にある中間インデックス ページ内の情報を使用して、キーを格納しているページに対して、直列先行読み取りのスケジュールを設定します。The storage engine uses the information in the intermediate index page above the leaf level to schedule serial read-aheads for the pages that contain the keys. ABC ~ DEF までのすべてのキーに対する要求が行われると、ストレージ エンジンは、まずリーフ ページの上にあるインデックス ページを読み取ります。If a request is made for all the keys from ABC to DEF, the storage engine first reads the index page above the leaf page. ただし、504 ページから 556 ページ (指定された範囲内で最後のキーを持つページ) までを単に順番に読み取るのではありません。However, it does not just read each data page in sequence from page 504 to page 556 (the last page with keys in the specified range). ストレージ エンジンは、中間インデックス ページをスキャンし、読み取りが必要なリーフ ページのリストを構築します。Instead, the storage engine scans the intermediate index page and builds a list of the leaf pages that must be read. 続けて、すべての読み取りをキー順にスケジュール設定します。The storage engine then schedules all the reads in key order. ストレージ エンジンは、ページ 504/505 と 527/528 が連続していることも認識し、単一のスキャッター読み取りを実行して、隣接するページを 1 回の操作で取得します。The storage engine also recognizes that pages 504/505 and 527/528 are contiguous and performs a single scatter read to retrieve the adjacent pages in a single operation. 直列操作で多くのページを取得する場合、ストレージ エンジンは一度に行う読み取りブロックのスケジュールを設定します。When there are many pages to be retrieved in a serial operation, the storage engine schedules a block of reads at a time. この読み取りのサブセットが終了すると、ストレージ エンジンは同じ数の新たな読み取りのスケジュールを設定します。これは必要とされるすべての読み取りのスケジュールが設定されるまで続きます。When a subset of these reads is completed, the storage engine schedules an equal number of new reads until all the required reads have been scheduled.

ストレージ エンジンは、プレフェッチを使用して非クラスター化インデックスからのベース テーブルの参照を高速化します。The storage engine uses prefetching to speed base table lookups from nonclustered indexes. 非クラスター化インデックスのリーフ行は、それぞれの特定のキー値を格納しているデータ行へのポインターを格納しています。The leaf rows of a nonclustered index contain pointers to the data rows that contain each specific key value. ストレージ エンジンは、非クラスター化インデックスのリーフ ページを読み取りながら、ポインターが既に取得されているデータ行の非同期読み取りをスケジュールに組み込みます。As the storage engine reads through the leaf pages of the nonclustered index, it also starts scheduling asynchronous reads for the data rows whose pointers have already been retrieved. これにより、ストレージ エンジンは非クラスター化インデックスのスキャンを完了する前に、基になるテーブルからデータ行を取得できます。This allows the storage engine to retrieve data rows from the underlying table before it has completed the scan of the nonclustered index. テーブルがクラスター化インデックスを保持しているかどうかに関係なく、プレフェッチが使用されます。Prefetching is used regardless of whether the table has a clustered index. SQL Server Enterprise は、SQL Server の他のエディションよりも多くプレフェッチを使用するため、より多くのページを先行して読み取ることができます。SQL Server Enterprise uses more prefetching than other editions of SQL Server, allowing more pages to be read ahead. いずれのエディションでも、プレフェッチのレベルは構成できません。The level of prefetching is not configurable in any edition. 非クラスター化インデックスの詳細については、「 非クラスタ化インデックスの構造」をご覧ください。For more information about nonclustered indexes, see Nonclustered Index Structures.

拡張スキャンAdvanced Scanning

SQL Server Enterprise の拡張スキャン機能により、複数のタスクがフル テーブル スキャンを共有できるようになります。In SQL Server Enterprise, the advanced scan feature allows multiple tasks to share full table scans. Transact-SQL ステートメントの実行プランがテーブルのデータ ページのスキャンを必要とし、そのテーブルが既に他の実行プラン用にスキャンされていることを データベース エンジンDatabase Engine が検出した場合、 データベース エンジンDatabase Engine は、2 番目のスキャンの現在位置で 2 番目のスキャンを 1 番目のスキャンに結合します。If the execution plan of a Transact-SQL statement requires a scan of the data pages in a table and the データベース エンジンDatabase Engine detects that the table is already being scanned for another execution plan, the データベース エンジンDatabase Engine joins the second scan to the first, at the current location of the second scan. データベース エンジンDatabase Engine は各ページを 1 回だけ読み取り、各ページの行を両方の実行プランに渡します。The データベース エンジンDatabase Engine reads each page one time and passes the rows from each page to both execution plans. この処理は、テーブルの最後まで行われます。This continues until the end of the table is reached.

この時点で、1 番目の実行プランはスキャンの完全な結果を所有していますが、2 番目の実行プランは進行中のスキャンに結合する前に読み取られたデータ ページを取得する必要があります。At that point, the first execution plan has the complete results of a scan, but the second execution plan must still retrieve the data pages that were read before it joined the in-progress scan. 2 番目の実行プランのスキャンは、折り返してテーブルの最初のデータ ページに戻り、1 番目のスキャンに結合した位置に達するまでスキャンを実行します。The scan for the second execution plan then wraps back to the first data page of the table and scans forward to where it joined the first scan. このようにして、スキャンはいくつでも組み合わせることができます。Any number of scans can be combined like this. データベース エンジンDatabase Engine は、すべてのスキャンを完了するまでデータ ページをループし続けます。The データベース エンジンDatabase Engine will keep looping through the data pages until it has completed all the scans. このメカニズムは、"メリーゴーラウンド スキャン" とも呼ばれます。また、このメカニズムは、ORDER BY 句が指定されていない SELECT ステートメントから返される結果の順序が保証されない理由を説明しています。This mechanism is also called "merry-go-round scanning" and demonstrates why the order of the results returned from a SELECT statement cannot be guaranteed without an ORDER BY clause.

たとえば、500,000 ページを持つテーブルがあるとします。For example, assume that you have a table with 500,000 pages. UserA が、このテーブルのスキャンを要求する Transact-SQL ステートメントを実行します。UserA executes a Transact-SQL statement that requires a scan of the table. このスキャンが 100,000 ページを処理した時点で、UserB が同じテーブルをスキャンする別の Transact-SQL ステートメントを実行します。When that scan has processed 100,000 pages, UserB executes another Transact-SQL statement that scans the same table. データベース エンジンDatabase Engine は、100,001 ページ以降のページに対する 1 セットの読み取り要求をスケジュールに組み込み、各ページの行を両方のスキャンに渡します。The データベース エンジンDatabase Engine schedules one set of read requests for pages after 100,001, and passes the rows from each page back to both scans. スキャンが 200,000 ページ目に達した時点で、UserC が同じテーブルをスキャンする別の Transact-SQL ステートメントを実行します。When the scan reaches the 200,000th page, UserC executes another Transact-SQL statement that scans the same table. データベース エンジンDatabase Engine は、200,001 ページから読み取った各ページの行を 3 つのスキャンすべてに渡します。Starting with page 200,001, the データベース エンジンDatabase Engine passes the rows from each page it reads back to all three scans. 500,000 行目を読み取った時点で、UserA のスキャンは完了します。UserB と UserC のスキャンは、先頭に戻って 1 ページから読み取りを開始します。After it reads the 500,000th row, the scan for UserA is complete, and the scans for UserB and UserC wrap back and start to read the pages starting with page 1. データベース エンジンDatabase Engine が 100,000 ページに到達すると、UserB のスキャンが完了します。When the データベース エンジンDatabase Engine gets to page 100,000, the scan for UserB is completed. UserC のスキャンは 200,000 ページを読み取るまで処理を続けます。The scan for UserC then keeps going alone until it reads page 200,000. このページ時点ですべてのスキャンが完了したことになります。At this point, all the scans have been completed.

拡張スキャンを使用しなければ、ユーザーが互いにバッファー領域の確保を求めて競合することになり、ディスク アームの競合が発生します。Without advanced scanning, each user would have to compete for buffer space and cause disk arm contention. また、一度読み取られたページを複数のユーザーが共有するのではなく、同じページがユーザーごとにその都度読み取られるため、パフォーマンスが低下し、リソースに負荷がかかります。The same pages would then be read once for each user, instead of read one time and shared by multiple users, slowing down performance and taxing resources.

参照See Also

ページとエクステントのアーキテクチャ ガイド Pages and Extents Architecture Guide
ページの書き込みWriting Pages