Исходный заказ на размещение с кластеризованным индексом

У меня вопрос по кластеризованному индексу.

В кластеризованных индексах узлы листового уровня сами содержат данные в отсортированном порядке, верно?

То есть при каждой вставке/обновлении/удалении узлы перетасовываются для сохранения отсортированного порядка.

Так как же можно извлечь из него данные в том порядке, в котором они были вставлены?

Представьте, что следующие данные вставляются в указанном порядке: 1,7,4,5,2 и для этого поля создается кластеризованный индекс.

Таким образом, данные будут храниться внутри в порядке 1,2,4,5,7, верно?

Таким образом, это может ускорить поиск определенного значения, но что, если пользователю нужны первые 3 значения в том порядке, в котором он был вставлен?

Можно ли их как-то восстановить, или мне нужно назначать добавочный идентификатор для каждой вставленной строки, объявлять для нее некластеризованный индекс и предоставлять данные для первых 3 записей на основе сортировки записей в этом поле идентификатора?


person SexyBeast    schedule 01.07.2012    source источник
comment
Да, вам нужно будет добавить дополнительный столбец, представляющий либо добавочный суррогат, например. идентификатор INT или, альтернативно, некоторая форма механизма автоматической отметки времени для повторного отслеживания исходного порядка вставки.   -  person StuartLC    schedule 01.07.2012
comment
Итак, как выбрать, создавать ли кластеризованный индекс для значения поля или кластеризованный индекс для значения id? Это похоже на то, что когда запросы, которые приходят чаще, относятся к этому типу Выберите 6 строк, начиная с 3-й строки, я должен выбрать идентификатор в качестве кластерного ключа, а когда запросы типа Выберите запись, где значение = 45 встречается чаще, я должен установить кластерный индекс на значение поля?   -  person SexyBeast    schedule 01.07.2012
comment
Но я только что узнал, что я не могу создать более 1 кластеризованного индекса в одной таблице, а также не могу создать как кластеризованные, так и некластеризованные индексы в одной таблице. Итак, как я могу создать 2 индекса (один из которых должен быть по крайней мере сгруппирован для облегчения быстрого поиска) для 2 разных полей здесь?   -  person SexyBeast    schedule 01.07.2012
comment
Вы можете создать множество некластеризованных индексов для таблицы в дополнение к нулю или одному кластеризованному индексу.   -  person Martin Smith    schedule 02.07.2012


Ответы (3)


(Ответы основаны на SQL Server - вопрос не указан на 100%)

В кластеризованных индексах узлы листового уровня сами содержат данные в отсортированном порядке, верно?

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

То есть при каждой вставке/обновлении/удалении узлы перетасовываются для сохранения отсортированного порядка.

Узлы (например, страницы разделены и меняются указатели вперед/назад в списке двойных ссылок), но внутри страницы массивы слотов по-прежнему являются сущностью, сохраняющей порядок, сами строки не будут перетасовываться, чтобы соответствовать порядку массива слотов.

Так как же можно извлечь из него данные в том порядке, в котором они были вставлены?

Обычно не гарантируется, что он будет в точном порядке - это чаще происходит на странице кучи, где массив слотов более репрезентативен для порядка, но опять же, не гарантируется.

Представьте, что следующие данные вставляются в указанном порядке: 1,7,4,5,2, и для этого поля создается кластеризованный индекс. Таким образом, данные будут храниться внутри в порядке 1,2,4,5,7, верно?

Нет, на странице он будет храниться как 1,7,4,5,2, но массив слотов будет считывать адреса на странице как 7,5,4,2,1 (он построен с конца страницы в обратном направлении). , так что вы читаете в обратном порядке.)

Таким образом, это может ускорить поиск определенного значения, но что, если пользователю нужны первые 3 значения в том порядке, в котором он был вставлен?

В этом случае это не имеет значения - кроме отсутствия такой гарантии порядка, SQL будет считывать всю страницу в память. Если вы хотите узнать больше о SQL Internals на таком уровне, я бы по-прежнему рекомендовал книгу Kalen Delaneys SQL Internals как один из лучших источников.

Если вам нужна какая-либо информация о порядке вставки, я предлагаю какую-то вставленную_временную метку

person Andrew    schedule 01.07.2012
comment
Это не совсем правильно, данные могут храниться в любом порядке на листе, но массив слотов на странице фактически соответствует порядку, в котором данные считываются со страницы, а не физическому порядку данных. — но я нашел на mssqltips.com/ sqlservertip/1254/clustered-tables-vs-heap-tables в разделе Кластеризованная таблица, что данные хранятся в порядке, основанном на ключе кластеризованного индекса. Пожалуйста, объясните, какой из них правильный, или это по сути одно и то же утверждение. - person SexyBeast; 01.07.2012
comment
Они представляют собой объяснения различной глубины технических подробностей. Вы можете рассматривать его на высоком уровне как хранящемся в порядке, который не обращает внимания на то, как SQL Server физически это делает, - на более подробном уровне вы узнаете о страницах, массивах слотов и о том, как кластеризованный индекс поддерживает порядок и т. д. - person Andrew; 01.07.2012
comment
Пожалуйста, объясните, что означает сохранение данных в слотах массива в одном порядке, а чтение в другом порядке. Во всех книгах, которые я просматриваю, говорится, что в кластерном индексе конечные узлы — это места, где хранятся данные (в отличие от некластеризованного, где они являются просто указателями на фактические страницы данных), и они хранятся в порядок сортировки, и сервер поддерживает порядок сортировки при каждом обновлении/вставке/удалении. - person SexyBeast; 01.07.2012
comment
Они хранятся в двойном связанном списке страниц, просматривайте этот список по порядку, и у вас есть порядок кластеризованного индекса. Это ничего не говорит о том, как страницы хранятся на диске или в порядке ли данные на отдельной странице, массив слотов - это порядок на отдельной странице. Полные объяснения требуют гораздо больше места/времени, чем комментарии к вопросу. - person Andrew; 02.07.2012
comment
Хорошо, тогда, пожалуйста, предоставьте ссылку/книгу, где я могу найти их в глубине. Я имею в виду, что ни одна из книг или веб-сайтов ничего не говорит о двусвязных списках и массивах слотов, все, что они говорят, это то, что конечные узлы содержат данные, и они отсортированы. - person SexyBeast; 02.07.2012
comment
Упомянутый в моем ответе - Кален Делани, SQL Server Internals - многие считают его библией Internals. Некоторые блоги также освещают этот уровень детализации, читайте блоги по sqlskills, например, Пола Рэндала: sqlskills.com /блоги/пол - person Andrew; 02.07.2012
comment
Но постойте, если в кластеризованном индексе конечные страницы содержат не данные, а скорее указатели (через двусвязные списки, как вы говорите), в чем разница между этим и некластеризованным индексом? В последнем случае конечные страницы также содержат указатели на фактические данные. - person SexyBeast; 02.07.2012
comment
Я не говорил, что конечные страницы не содержат данных. Конечная страница имеет заголовок (где находятся различные элементы, например указатели) и часть данных. - person Andrew; 02.07.2012
comment
давайте продолжим это обсуждение в чате - person Andrew; 02.07.2012

Похоже, вам нужна временная метка для ваших строк. Обычно я помещаю следующие столбцы во все создаваемые мной таблицы (для аудита):

timecreated
timemodified
createdby
modifiedby
deleted

Эти столбцы позволяют узнать, кто и когда создал строку, когда она была изменена в последний раз и кем, а также, при необходимости, «обратимо удалить» строку, установив для удаления значение true. Конечно, все ваши другие запросы в системе должны будут проверять удаленное логическое значение для работы мягкого удаления.

person Hogan    schedule 01.07.2012

Данные таблицы сортируются в соответствии с порядком кластеризованного индекса. У вас может быть только ОДИН кластеризованный индекс в каждой таблице, если вы хотите проверить первые 3 значения в том порядке, в котором он был вставлен,

ИСПОЛЬЗОВАТЬ AdventureWorks

go

CREATE TABLE myTable99(
Col1 int IDENTITY(1,1) PRIMARY KEY , Col2 Char(1) , Col3 datetime DEFAULT getdate()

) GO

INSERT INTO myTable99(Col2) SELECT 'A' UNION ALL SELECT 'B' UNION ALL SELECT 'C' GO

ВЫБЕРИТЕ * ИЗ myTable99 ЗАКАЗАТЬ ДО 3 GO

УДАЛИТЬ СТОЛ myTable99 GO

Другой метод может быть:

CREATE TABLE CounterData]( [CounterDataID] [bigint] IDENTITY(1,1) NOT NULL, [DateTimeID] [bigint] NOT NULL, [Value] [float] NULL ) ON [PRIMARY]

СОЗДАЙТЕ УНИКАЛЬНЫЙ КЛАСТЕРНЫЙ ИНДЕКС [IX_DateTime_CounterDataID] НА [PK].[CounterData]

(

[DateTimeID] ASC,
[CounterDataID] ASC

)

С

(PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO

person Community    schedule 01.07.2012
comment
Таким образом, в основном вы говорите, что для хранения дополнительной части данных (в данном случае метки времени) в качестве суррогата и последовательного извлечения записи на основе этого, в то время как случайным образом на основе кластерного индекса самим сервером, верно? - person SexyBeast; 01.07.2012