Страницы: Что SQL Server помещает в файлы

Tags: SQL Server, индекс

В каждом файле данных базы данных (MDF) SQL Server хранит ваши данные на страницах размером 8 КБ. Это килобайты - не мегабайты, не гигабайты, а всего лишь килобайты.

К примеру, мы создаем таблицу:

CREATE TABLE dbo.Employees

(EmployeeID INT IDENTITY(1,1),

 EmployeeName VARCHAR(200))

 

Во-первых, да, я понимаю, я не должен делать EmployeeName как одно поле - у меня должны быть FirstName, LastName, MiddleName, Suffix, Prefix и т.д., но я стараюсь сократить это письмо максимально.

 

Тем не менее, в этой таблице, каждая запись занимает немного места. EmployeeID - это INTeger, который занимает 4 байта. Это те же 4 байта, независимо от того, это число равно 1 или 1 000 000. EmployeeName  - это VARCHAR (200), что означает, мы можем хранить до 200 символов здесь, и каждый символ занимает байт. Если мы вставим 'BRENT OZAR', это 10 символов, поэтому нам нужно 10 байтов, чтобы сохранить это.

 

Если все наши сотрудники в среднем содержат около 10 символов, это означает, что мы можем разместить около 500-600 записей на странице базы данных размером 8 КБ.

 

Brent Ozar Unlimited - небольшая компания, поэтому мы можем хранить всех наших сотрудников на одной странице размером 8 КБ. Когда мы добавляем, редактируем и удаляем сотрудников, SQL Server забирает эту 8KB-страницу с диска, вносит ее в память, вносит необходимые изменения, а затем записывает эту страницу данных обратно на диск. Сама страница размером 8 КБ - это самый маленький блок, который будет кэшироваться SQL Server - он не кэширует отдельные строки / записи - и каждая страница принадлежит исключительно одному объекту.

 

Немного про объекты

Вы заметите, что я избегаю использования слова «таблица». Таблицы классные, но когда мы начинаем разбираться с тем, что SQL Server делает, мы хотим начать думать об этих трех типах объектов:

 

Куча - это специализированная структура данных типа дерево. В моей таблице dbo.Employees я не указывал, в каком порядке SQL Server должен хранить мои данные, поэтому данные на моей странице размером 8 Кбайт будут удалены в любом порядке.

 

Кластеризованный индекс - то, что мы обычно считаем таблицей. Если бы я создал свою таблицу следующим образом:

 

CREATE TABLE dbo.Employees

(EmployeeID INT IDENTITY(1,1) PRIMARY KEY CLUSTERED,

 EmployeeName VARCHAR(200))

 

Тогда SQL Server будет хранить мои данные в порядке EmployeeID. Таким образом, когда я ищу EmployeeID # 42, он может перейти непосредственно к этому номеру без сканирования всех моих сотрудников. Индекс сортируется в порядке поля EmployeeID, но на самом деле это полная копия нашей таблицы, включая все наши поля - в данном случае это просто EmployeeName.

 

Некластеризованный индекс - Если я скажу SQL Server:

CREATE NONCLUSTERED INDEX IX_Name

ON dbo.Employees(EmployeeName)

 

Затем SQL Server создаст вторую копию моей таблицы, отсортированную по EmployeeName. Эта копия моей таблицы будет включать только поля, указанные в индексе (EmployeeName), а также все поля, необходимые для возврата к кластеризованному индексу (в данном случае, ключ кластеризации, EmployeeID).

Все три этих объекта - кучи, кластеризованные индексы и некластеризованные индексы - будут храниться на отдельных наборах страниц. У нас не будет кластеризованного индекса и некластеризованного индекса для той же таблицы на той же странице - они разделены. Поэтому, когда мы занимаемся анализом, мы должны думать не о таблицах, а об индексах. Чтобы узнать больше, прочитайте Jes Borland's SQL Server Index Terms.

 

Страницы и строки на диске

The sys.dm_db_index_physical stats

Функция динамического управления (DMF) возвращает количество строк и страниц, хранящихся в каждом объекте базы данных. Он принимает параметры за идентификатор базы данных и идентификатор объекта, также вы можете передавать NULL для получения информации по всем вашим объектам базы данных. Прокрутите страницу до ссылки примеров на странице «Books Online», и вы получите запросы для изучения одной таблицы. Я настоятельно рекомендую начать с небольшой таблицы, потому что некоторые параметры DMF заставят SQL Server фактически искать на каждой странице объекта. Это означает, что, если все страницы этого объекта не кэшируются в памяти, работа вашего SQL Server может замедлиться.

 

DMF также включает в себя средний размер записи и максимальный размер записи. Просто потому, что мы делаем все VARCHAR (8000), не означает, что мы фактически сохраняем 8000 символов в каждом поле. Но пока не меняйте структуру базы данных. Давай оставим это на потом.

 

Вы можете получить похожие метаданные гораздо быстрее, используя sp_spaceused, но не получите классную информацию о среднем размере записи.

 

Подробнее о страницах

На моей 90-минутной сессии «How to Think Like the Engine» я объясняю страницы, индексы, объединения и т. Д. Я использую реальные страницы базы данных из базы данных StackOverflow.com для демонстрации, и вы фактически получаете PDF-файлы, которые вы можете распечатать и следовать им по ходу дела.

 

Ваше домашнее задание

Давайте начнем думать о том, какие объекты занимают место в наших базах данных.  Является ли ваша база данных сокровищницей, хватающейся за кучу некластеризованных индексов, которые не используются, а просто занимают место? Насколько велик каждый индекс, и будет ли он использоваться или нет?

 

Это важно, потому что чем больше индексов вы имеете:

  • тем дольше происходит резервное копирование
  • тем больше памяти вам нужно для кэширования
  • И что самое главное, тем медленнее будут ваши вставки / обновления / удаления, так как SQL Server должен будет хранить больше копий вашей таблицы

 

No Comments

Add a Comment