Считывание страницReading Pages

ОБЛАСТЬ ПРИМЕНЕНИЯ: даSQL Server нетБаза данных SQL AzureнетХранилище данных SQL AzureнетParallel Data WarehouseAPPLIES TO: yesSQL Server noAzure SQL Database noAzure SQL Data Warehouse noParallel Data Warehouse

Процесс ввода-вывода экземпляра компонента Компонент Database EngineDatabase Engine в базе данных SQL Server включает физические и логические операции чтения.The I/O from an instance of the SQL Server Компонент Database EngineDatabase Engine includes logical and physical reads. Логическое чтение выполняется каждый раз, когда компонент Компонент Database EngineDatabase Engine запрашивает страницу из буферного кэша.A logical read occurs every time the Компонент Database EngineDatabase 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 EngineDatabase Engine на чтение страниц управляются реляционным механизмом, а их дополнительную оптимизацию выполняет подсистема хранилища.The read requests generated by an instance of the Компонент Database EngineDatabase 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 EngineDatabase Engine поддерживает механизм оптимизации производительности, называемый упреждающим чтением.The Компонент Database EngineDatabase 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. Это позволяет распараллелить операции вычисления и ввода-вывода, полностью задействовав процессорные и дисковые мощности.This allows computation and I/O to overlap, taking full advantage of both the CPU and the disk.

Механизм упреждающего чтения позволяет компоненту Компонент Database EngineDatabase Engine считывать из одного файла до 64 последовательных страниц (512 КБ).The read-ahead mechanism allows the Компонент Database EngineDatabase 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.

Упреждающее чтение бывает двух видов: для страниц данных и для страниц индексов.There are two kinds of read-ahead: one for data pages and one for index pages.

Чтение страниц данныхReading Data Pages

Просмотр таблиц для чтения страниц данных выполняется в компоненте Компонент Database EngineDatabase Engineвесьма эффективно.Table scans used to read data pages are very efficient in the Компонент Database EngineDatabase Engine. Страницы карты распределения индекса (IAM) в базе данных SQL Server содержат указатели на экстенты, используемые таблицей или индексом.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. Это позволяет подсистеме хранилища оптимизировать операции ввода-вывода выполняемые последовательно в виде больших операций чтения на основе их размещения на диске.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 являются смежными, и считывает содержащиеся на них данные за одну операцию, после чего выполняет сборку данных.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 EngineDatabase Engine обнаружил, что таблица уже просматривается в отношении другого плана выполнения, то компонент Компонент Database EngineDatabase Engine присоединяет вторую операцию просмотра к первой в том месте, где она в данный момент находится.If the execution plan of a Transact-SQL statement requires a scan of the data pages in a table and the Компонент Database EngineDatabase Engine detects that the table is already being scanned for another execution plan, the Компонент Database EngineDatabase Engine joins the second scan to the first, at the current location of the second scan. Компонент Компонент Database EngineDatabase Engine считывает по странице за раз и передает полученные строки каждой считываемой страницы обоим планам выполнения.The Компонент Database EngineDatabase 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.

На этой стадии первый план выполнения получит полные результаты просмотра, а второй план до сих пор не получил страницы данных, находящиеся ранее места присоединения.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. Поэтому для него производится возврат к первой странице данных, и просмотр повторяется до этой точки.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 EngineDatabase Engine продолжает циклическое считывание страниц данных до тех пор, пока не будут завершены все операции просмотра.The Компонент Database EngineDatabase Engine will keep looping through the data pages until it has completed all the scans. Этот механизм называется также «кольцевым просмотром» и демонстрирует, почему порядок строк, возвращаемых в результате выполнения инструкции SELECT, без предложения ORDER BY не гарантирован.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. Для считывания после 100 001-ой страницы компонент Компонент Database EngineDatabase Engine запланирует всего одну серию запросов и будет возвращать полученные строки обоим планам выполнения.The Компонент Database EngineDatabase 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. Начиная с 200 001-ой страницы, компонент Компонент Database EngineDatabase Engine будет передавать строки каждой считываемой страницы всем трем просмотрам.Starting with page 200,001, the Компонент Database EngineDatabase Engine passes the rows from each page it reads back to all three scans. После считывания 500000-й строки просмотр для пользователя UserA завершается, а для пользователей UserB и UserC чтение снова начинается с первой страницы.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 EngineDatabase Engine доходит до 100000-й страницы, просмотр для пользователя UserB завершается.When the Компонент Database EngineDatabase Engine gets to page 100,000, the scan for UserB is completed. Просмотр для пользователя UserC продолжает выполняться до тех пор, пока не будет достигнута 200000-я страница.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