Проблема в том, что doco - это болтовня, и это усиливает само замешательство, которое, как он утверждает, проясняет. Если вы забудете обо всем этом и начнете заново, это будет довольно просто. Поскольку вы запрашиваете структуры хранения данных и заботитесь о производительности, давайте посмотрим на эту перспективу (не логическую). Нет структуры хранения данных с именем «Таблица».
Heap
Страницы данных, содержащие строки. Нет кластерного индекса. Строки не сдвигаются в результате вставок / удалений. Строки могут быть прочитаны полностью (сканирование таблицы) или по одному (через некластеризованный индекс). Это становится сильно фрагментированным.
Кластерный индекс
B-Tree. Индекс кластеризован со строками данных. Конечный уровень равен строке данных. Это означает, что на каждый доступ уменьшается на один ввод-вывод. Это также означает, что B-Tree уменьшается на один уровень в высоте индекса (поэтому они маленькие, если вы их осмотрели). Куча (вся структура хранения данных) устранена. Там нет указателей. Строки поддерживаются в порядке ключа кластерного индекса (строки перемещаются на странице в результате операции вставки / удаления / расширения). Страницы обрезаны в пределах экстентов.
Некластеризованный индекс
B-Tree. Полная высота в соответствии с количеством строк.
Там, где есть кластеризованный индекс, уровень листьев является ключом кластеризованного индекса (чтобы он мог перейти к точному местоположению в CI, который является строкой).
Там, где нет кластерного индекса, уровень листа является указателем: File: Page: Offset (чтобы он мог перейти к куче и получить строку). RowIds в куче не изменяются (если они изменились, каждый раз, когда вы вставляли / удаляли одну строку, вам пришлось бы обновлять все записи NCI во всех связанных NCI для всех других строки на странице).
Именно поэтому, когда вы создаете CI, все NCI автоматически перестраиваются (их необходимо переключить с [2] на 1 ). Очевидно, всегда создавайте CI до NCI.
Файл: Страница: Слот отсутствует, длина строки является переменной, она смещена в пределах страницы.
Нет закладки или другого goobledegook.
Re "Нет прямого доступа к строке данных в кластеризованной таблице - почему"
Ерунда. У вас есть прямой и немедленный доступ к каждой строке данных через CI (на один меньше I / O) или NCI⇢CI Key.
Это очень быстро, изобретено Бриттоном Ли; повторно внедрен и запатентован Sybase; полученные нечестным путем и за гроши Дартом Вейдером.
Если вам нужны дополнительные разъяснения, я могу предоставить иллюстрации.
Ответы на комментарии
"Это также означает, что B-дерево уменьшается на один уровень высоты индекса (поэтому они маленькие, если вы их осматриваете)."
Допустим, у вас есть таблицы с 1 миллиардом строк. «Высота» B-дерева любого заданного индекса (например, уникального на PK), нарисованного вертикально, скажем, 8; или вы можете сказать, что индекс имеет глубину 8 уровней, между верхним (одна запись) и нижним, уровень листа. уровень листьев, конечно, самый широкий и наиболее опыленный; в нем будет 1 миллиард записей. Учитывая, что каждая индексная страница содержит, скажем, 256 записей, уровень leaf-minus-one содержит 390K записей.
B-дерево CI (часть только для индекса) будет содержать 7 уровней, 390 тыс. Записей, занимающих 10 МБ; потому что конечный уровень - это строка данных (из которых 1 миллиард записей, хорошо распределенных по 100 ГБ), и поэтому исключается или не повторяется.
Да, я хотел бы иллюстрации.
Ok.У меня есть набор готовых документов Sybase;Я вырезал один для вас, чтобы избежать путаницы, и исключил биты, которые есть у Sybase, а у MS нет.Сожалею.Не переходите по ссылкам, просто оставайтесь на одной странице.Кроме того, очень низкие уровни фрагментации в куче отличаются тем, что фрагментация в куче огромна, как в Sybase, так и в MS, поэтому я оставил это без изменений.
Основы хранения данных
(Это сжатая версия моих гораздо более сложных диаграмм Sybase, которые я вырезал для контекста MS. Внизу этого документа есть ссылка, если вам нужен полный набор Sybase.)
"Я начал читать: Разоблачение мифов о кластеризованных индексах - часть 4 (CIX, TPC-C и кластеры Oracle) ив нем, как и во многих других источниках, прямо упоминается тот факт, что в SQL Server, в отличие от Oracle, отсутствуют функции прямого доступа к кластерной таблице. "
Будьте внимательны при чтении, сеть переполненаповерхностной информации;половина правды обсуждается вне контекста;дезинформация (как от продавцов, так и от невежественных из лучших побуждений).Как вы заметили, я просто отвечаю на вопросы;Я не трачу время на ответы на вопросы, поднятые в ссылках.
Просто подумайте об этом.Хорошо реализованные таблицы с КИ не нуждаются в дефрагментации;а при плохой реализации требуется нечастая дефрагментация;таблицы без CI нуждаются в частой и в значительной степени автономной дефрагментацииЭто ваше окно обслуживания в понедельник утром.Просто пример того, почему обсуждение предметов в действительности является дезинформацией.Вот почему все мои документы связаны и связаны друг с другом.
"Несколько респондентов ссылались на тот факт, что ключ CI в листе NCI предназначен для независимости адреса в случае разбиения страницы."
Да, я бы так не сказал, это так же запутанно, как и первое упоминание, которое вы опубликовали.Разделение страниц не имеет к этому никакого отношения.Я поставил именно так, как я сделал в своем посте, специально для ясности.Поскольку строки перемещаются (CI сохраняет обрезку страниц и экстентов), NCI ДОЛЖЕН иметь ключ CI, чтобы найти строку.Он не может использовать RowId, который будет постоянно меняться.Если у вас нет широких CI-ключей, это не страшно;4-байтовый RowId (плюс накладные расходы на обработку) против 8-байтового ключа CI (за вычетом накладных расходов) ... кого это волнует (хорошо, может быть, вы).Решите проблемы более высокого уровня, и проблемы низкого уровня будут достаточно малы, чтобы не требовать решения.Выжимать 1% улучшения производительности на низком уровне, когда ваша БД фрагментирована и ненормализована, более чем немного глупо.
Система в интегрированном наборе компонентов, ни один из которых не может быть изменен или оценен изолированно.Компоненты, которые не интегрированы, являются не интегрированными, а не системой.На вашем уровне допроса вы еще не в состоянии сделать выводы или иметь недовольство тем или иным, если вы делаете, это преждевременные выводы и обиды, которые будут препятствовать вашему прогрессу.Кроме того, существует большая разница между знаниями, полученными с помощью вопросов и ответов, и знаниями, полученными при чтении и опыте.
"Не во время повторной инициализации или дефрагментации некластеризованной таблицы.с CI строки перемещены и соответствующие RID в NCI изменяются в NCI? "
Вы имеете в виду " некластеризованный INDEX с CI "?Ну, NCI не стоит де-фрагментировать, просто удалите / создайте их.
Или вы имеете в виду "дефрагментация CI [вся таблица]" ?Я уже писал, что когда вы воссоздаете CI (или де-фрагментируете его на месте), NCI автоматически перестраиваются.Речь идет не о RowIds, а об изменении: когда вы удаляете CI, NCI должны быть переписаны из ключей CI в RowIds;когда вы создаете CI, NCI должны быть изменены на CI Keys.Включенные администраторы баз данных сбрасывают NCI перед сбросом CI.
«Мне кажется, что это устранение недостатка схемы - строка должна была двигаться со своим адресом, не так ли?» Вы получаете слишком низкий уровень, не понимая более высоких уровней.Если строка перемещается, ее адрес изменяется;если адрес меняется, строка перемещается.Либо у вас есть CI (строки перемещаются), либо у вас есть куча (строки не перемещаются).
"Кроме того, полностью ли защищена куча от разбиения страниц?"
Нет.Разделение страницы по-прежнему происходит, когда строки переменной длины расширяются и на странице нет места.Но в схеме вещей, массивная фрагментация в кучах, из-за того, что строки не движутся, из-за того, что она основана на RowId (на которую полагаются NCI), это небольшой элемент.