7

У меня есть пара таблиц (User & UserRecord) в моей базе данных, которые чрезвычайно фрагментированы (например, 99%) и приводят к тому, что вся база данных и, следовательно, сайт остановится.Проблемы с фрагментацией SQL Server

UserRecord - это как моментальный снимок этого пользователя в определенный момент времени. Пользователь похож на основную запись для этого пользователя. Пользователь имеет от 0 до многих UserRecords. У пользователя около миллиона строк, у UserRecord около 2,5 миллионов. Эти таблицы написаны много. Их также много разыскивают. Они оба получат намного больше. Основные индексы, которые сильно фрагментированы, являются первичными ключами таблиц User и UserRecord.

DB - это SQL Server 2012, и я использую Entity Framework, и я не использую какие-либо хранимые процедуры.

Таблицы выглядеть примерно так:

USER 
UserName string PK ClusteredIndex 
FirstName string 
LastName string 
+SeveralMoreRows 

USER_RECORD 
UserRecordId int PK ClusteredIndex 
ListId int FK(List) 
UserName string FK(User) NonClusteredIndex 
Community string NonClusteredIndex 
DateCreated datetime 
+LotsMoreRows 

LIST 
ListId int PK & ClusteredIndex 
Name string 
DateCreated datetime 

(не уверен, что если список это важно или нет, но думал, что я включить его, как это связано с User_Record Список содержит от 0 до многих UserRecords.)

Мы установили план обслуживания SQL для ежедневного восстановления индексов, который действительно помогает, но иногда этого недостаточно.

Друг предложил использовать две базы данных: одну для чтения, одну для записи, и мы синхронизируем чтение DB из БД записи. Не то, чтобы я ничего не знал об этом, но первая проблема, которую я вижу в этом решении, - это то, что нам нужно обновлять данные при просмотре сайта. Например, если мы обновляем данные пользователя или UserRecord, мы хотим немедленно увидеть эти изменения.

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

+0

Каковы определения таблиц? Используете ли вы GUID в качестве первичных ключей? –

+0

Вы используете кластеризованный индекс в столбце uniqueidentifier? это часто приводит к фрагментации после некоторых вставок ... потому что значения являются случайными ... – PrfctByDsgn

+0

Я добавил некоторые дополнительные сведения к вопросу – Owen

ответ

5

Кластерные индексы контролируют порядок данных на ДИСКЕ. Это одна из основных причин, почему обычно рекомендуется установить всегда увеличивающийся целочисленный ключ, чтобы действовать как кластеризованный индекс. Таким образом, когда в таблицу добавлено больше данных, они добавляются в конец существующих данных.

Если он не является автоматически увеличивающимся номером, а новые строки могут содержать значения, которые будут упорядочены где-то между существующими значениями, то SQL Server будет в основном выталкивать данные на диск, где он принадлежит (чтобы сохранить порядок значений кластерного ключа индекса), производя фрагментацию и потенциально серьезные накладные расходы, поскольку IO пишет о дальнейшем замедлении базы данных.

Я подозреваю, что у вас такая же проблема с вашими значениями UserRecord.

Итак, что бы я сделал, добавьте отдельный кластеризованный автоматически увеличивающий первичный ключ для каждой таблицы и переработайте свои ссылки FK & при необходимости.

+0

Почему бы не объявить индекс PK некластеризованным? –

+0

Обычно лучше всего иметь кластерный индекс на столе. Даже если вы оставите его и создайте некластеризованный ПК, он сохранит таблицу как HEAP, которая имеет ряд других проблем. Например, все запросы, которые будут выполняться против него, сначала должны будут найти соответствие некластеризованного индекса, а затем найти соответствующие строки из HEAP, чтобы получить другие значения, поскольку они не прибывают так же, как и кластерный индекс. Опять же, производство ненужных накладных расходов замедляет работу БД. В Google есть несколько хороших статей по таблицам HEAP и CLUSTERED. – Kahn

+1

Спасибо, звучит как SQL Server чрезвычайно отличается от других СУБД (например, Postgres, Oracle), когда дело доходит до индексирования. –