2

Я импортирую довольно здоровенный объем данных в базу данных SQL Server. Исходные данные берутся из PgSql (включая таблицы defs), которые я прохожу через некоторое простое регулярное выражение для перевода в TSql. Это создает таблицы без первичного ключа.Является ли добавление первичного ключа причиной реструктуризации базовых данных

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

После завершения импорта, добавить первичные ключи следующим образом:

ALTER TABLE someTable ADD CONSTRAINT PK_someTable PRIMARY KEY (id); 

(обратите внимание на отсутствие CLUSTERED ключевого слова). Что происходит сейчас? Еще куча? Что влияет на поиск по первичному ключу? Разве это действительно отличается от добавления стандартного индекса?

Теперь, вместо того, чтобы сказать, добавить первичные ключи следующим образом:

ALTER TABLE someTable ADD CONSTRAINT PK_someTable PRIMARY KEY CLUSTERED (id); 

Я принимаю это теперь полностью перестраивает таблицу в основе структуры строк с более эффективного поиска с помощью ПК, но менее желательными характеристиками вставки.

Являются ли мои предположения правильными?

Если мой импорт вставляет данные в заказ PK, есть ли какая-либо польза для отказа от ПК в первую очередь?

+0

Вы хотите вставить строки, а затем вы хотите добавить PK? –

+0

Я тоже могу это сделать, но учитывая объем данных, я бы лучше понял, что происходит, чем потратить 5-8 часов на тестирование разных сценариев. Я могу либо добавить ключи до, либо после, но вставляются ** ** в порядке PK. – spender

+1

INSERT * должен быть * быстрее, если таблица целей - HEAP. Но общая (вставка, обновление, удаление, выбор) производительности для таблицы HEAP, которая имеет ПК (не кластерная), должна быть хуже производительности для кластеризованной таблицы. Взгляните на эту статью [SQL Server Best Practices Article] (http://technet.microsoft.com/en-us/library/cc917672.aspx). И если вы импортируете большой объем данных, вы должны взглянуть на [разбиение на таблицы (SQL2005 +)] (http://msdn.microsoft.com/en-US/library/ms345146%28v=SQL.90%29#sql2k5parti_topic24). –

ответ

3

При выполнении

ALTER TABLE someTable ADD CONSTRAINT PK_someTable PRIMARY KEY (id); 

если нет кластерного индекса someTable то PK будет кластерный PK. В противном случае, если перед выполнением ALTER .. ADD ... PRIMARY KEY (id) есть кластерный индекс, PK будет некластеризованным PK.

- Test # 1

BEGIN TRAN; 
CREATE TABLE dbo.MyTable 
(
    id INT NOT NULL, 
    Col1 INT NOT NULL, 
    Col2 VARCHAR(50) NOT NULL 
); 
SELECT i.name, i.index_id, i.type_desc 
FROM sys.indexes i 
WHERE i.object_id = OBJECT_ID(N'dbo.MyTable'); 
/* 
name index_id type_desc 
---- ----------- --------- 
NULL 0   HEAP 
*/ 
ALTER TABLE dbo.MyTable 
ADD CONSTRAINT PK_MyTable PRIMARY KEY (id); 

SELECT i.name, i.index_id, i.type_desc 
FROM sys.indexes i 
WHERE i.object_id = OBJECT_ID(N'dbo.MyTable'); 
/* 
name  index_id type_desc 
----------- ----------- --------- 
PK_MyTable 1   CLUSTERED 
*/ 
ROLLBACK; 

- Test # 2

BEGIN TRAN; 
CREATE TABLE dbo.MyTable 
(
    id INT NOT NULL, 
    Col1 INT NOT NULL, 
    Col2 VARCHAR(50) NOT NULL 
); 
SELECT i.name, i.index_id, i.type_desc FROM sys.indexes i WHERE i.object_id = OBJECT_ID(N'dbo.MyTable'); 
/* 
name index_id type_desc 
---- ----------- --------- 
NULL 0   HEAP 
*/ 
CREATE CLUSTERED INDEX ix1 
ON dbo.MyTable(Col1); 

SELECT i.name, i.index_id, i.type_desc FROM sys.indexes i WHERE i.object_id = OBJECT_ID(N'dbo.MyTable'); 
/* 
name index_id type_desc 
---- ----------- --------- 
ix1 1   CLUSTERED 
*/ 

ALTER TABLE dbo.MyTable 
ADD CONSTRAINT PK_MyTable PRIMARY KEY (id); 

SELECT i.name, i.index_id, i.type_desc FROM sys.indexes i WHERE i.object_id = OBJECT_ID(N'dbo.MyTable'); 
/* 
name  index_id type_desc 
---------- ----------- ------------ 
ix1  1   CLUSTERED 
PK_MyTable 2   NONCLUSTERED 
*/ 
ROLLBACK; 
+1

Отличный ответ. Я бы +2, если бы мог. Спасибо. – spender

+0

Любые мысли о моей последней проблеме? – spender

1

В SQL Server, а первичные ключи по умолчанию сгруппированы, если не кластерный индекс не существует. Кластеризованный индекс действительно означает, что «индекс» не хранится в отдельной области хранения (как и некластеризованный индекс), но данные индекса «перемежаются» с соответствующими данными обычной таблицы. Если вы об этом узнаете, вы поймете, что они могут быть только одним кластерным индексом.

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

Например, если вы используете первичный ключ SSN, вы не получите большого преимущества, если только вы не обрабатываете данные, упорядоченные по порядку по SSN, хотя вы получаете преимущество из-за близости данных. Но, если вы можете предварять ввод SSN, кластеризованный ключ является большим преимуществом.

Итак, кластеризованный индекс переупорядочивает данные так, чтобы он был сгруппирован с кластеризованным индексом.

+0

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

0

Спасибо за приятную демонстрацию темы!

Выводы в вышесказанном не неправильный, но он показывает структуру индекса, а не таблицы. Я думаю, что следующий SQL будет отображаться информация для самой таблицы:

select 
    o.name, 
    o.object_id, 
    case 
     when p.index_id = 0 then 'Heap' 
     when p.index_id = 1 then 'Clustered Index/b-tree' 
     when p.index_id > 1 then 'Non-clustered Index/b-tree' 
    end as 'Type' 
from sys.objects o 
inner join sys.partitions p on p.object_id = o.object_id 
where o.name = 'MyTable'; 

Вы увидите, что MyTable кластеризован:

name object_id Type 
------- ----------- ------------------- 
MyTable 1237579447 Clustered Index/b-tree 

 Смежные вопросы

  • Нет связанных вопросов^_^