Самое плохое в вставках не по порядку - это разбиение на страницы.
Когда SQL Server
необходимо вставить новую запись в существующую страницу индекса и не найти там места, она берет половину записей со страницы и перемещает их в новую.
Скажем, у вас есть записи, заполняющие всю страницу:
1 2 3 4 5 6 7 8 9
и нужно вставить 10
. В этом случае SQL Server
просто запустит новую страницу.
Однако, если у вас есть это:
1 2 3 4 5 6 7 8 11
, 10
должно идти до 11
. В этом случае SQL Server
переместит записи с 6
на 11
на новую страницу:
6 7 8 9 10 11
Старая страница, как это легко увидеть, останется наполовину заполненной (туда попадут только записи с 1
до 6
, которые очень).
Это увеличит размер индекса.
Давайте создадим две таблицы примеров:
CREATE TABLE perfect (id INT NOT NULL PRIMARY KEY, stuffing VARCHAR(300))
CREATE TABLE almost_perfect (id INT NOT NULL PRIMARY KEY, stuffing VARCHAR(300))
;
WITH q(num) AS
(
SELECT 1
UNION ALL
SELECT num + 1
FROM q
WHERE num < 200000
)
INSERT
INTO perfect
SELECT num, REPLICATE('*', 300)
FROM q
OPTION (MAXRECURSION 0)
;
WITH q(num) AS
(
SELECT 1
UNION ALL
SELECT num + 1
FROM q
WHERE num < 200000
)
INSERT
INTO almost_perfect
SELECT num + CASE num % 5 WHEN 0 THEN 2 WHEN 1 THEN 0 ELSE 1 END, REPLICATE('*', 300)
FROM q
OPTION (MAXRECURSION 0)
EXEC sp_spaceused N'perfect'
EXEC sp_spaceused N'almost_perfect'
perfect 200000 66960 KB 66672 KB 264 KB 24 KB
almost_perfect 200000 128528 KB 128000 KB 496 KB 32 KB
Даже при вероятности выхода из строя только 20%
таблица становится вдвое больше.
С другой стороны, наличие кластерного ключа на Sequence
уменьшит I/O
в два раза (поскольку это можно сделать с помощью одного кластеризованного поиска индекса, а не двух некластеризованных).
Таким образом, я бы взял примерное подмножество ваших данных, вставил бы их в тестовую таблицу с кластеризованным индексом на Sequence
и измерил размер результирующей таблицы.
Если он меньше чем в два раза размер той же таблицы с индексом на ID
, я бы пошел на кластеризованный индекс на Sequence
(так как итоговое значение I/O
будет меньше).
Если вы решили создать кластеризованный индекс на Sequence
, сделайте ID
некластеризованным PRIMARY KEY
и сделайте кластеризованный индекс UNIQUE
на Sequence, ID
. Это будет использовать значимый ID
вместо непрозрачного уникального.