1

EDIT: Я добавил столбец «Slug» для решения проблем производительности при выборе конкретной записи.Умный выбор для первичного ключа и кластерного индекса в таблице в SQL 2005 для повышения производительности при выборе одной записи или нескольких записей

У меня есть следующие столбцы в моем столе.

Id Int - Primary key (identity, clustered by default) 
Slug varchar(100) 
... 
EntryDate DateTime 

В большинстве случаев я заказываю выписку с помощью EntryDate, как показано ниже.

Select T.Id, T.Slug, ..., T.EntryDate 
From (
    Select Id, Slug, ..., EntryDate, 
     Row_Number() Over (Order By EntryDate Desc, Id Desc) AS RowNum 
    From TableName 
    Where ... 
) As T 
Where T.RowNum Between ... And ... 

Я заказываю его по адресу EntryDate и Id в случае наличия дубликатов записей.

Когда я выбираю запись, я делаю следующее.

Select Id, Slug, ..., EntryDate 
From TableName 
Where Slug = @slug And Year(EntryDate) = @entryYear 
    And Month(EntryDate) = @entryMonth 

У меня есть уникальный ключ Slug & EntryDate.

Что было бы разумным выбором ключей и индексов в моей ситуации? Я сталкиваюсь с проблемами производительности, вероятно, потому, что я заказываю столбцом, который не кластеризован индексироваться.

Должен ли я установить Id как некластеризованный первичный ключ и EntryDate в качестве кластерного индекса?

Я ценю всю вашу помощь. Благодарю.

EDIT:

Я не пытался добавить некластеризованной индекс на EntryDate. Данные, вставленные из back-end, поэтому производительность для вставки для меня не большая. Кроме того, EntryDate не всегда является датой ее вставки. Это может быть прошлая дата. Конечный пользователь выбирает дату.

ответ

1

Основываясь на текущей схеме таблицы, вам нужны такие индексы, как это.

CREATE INDEX IX_YourTable_1 ON dbo.YourTable 
(EntryDate, Id) 
INCLUDE (SLug) 
WITH (FILLFACTOR=90) 

CREATE INDEX IX_YourTable_2 ON dbo.YourTable 
(EntryDate, Slug) 
INCLUDE (Id) 
WITH (FILLFACTOR=80) 

Добавить любые другие столбцы, которые вы возвращаете в строку INCLUDE.

Измените свой второй запрос на что-то вроде этого.

Select Id, Slug, ..., EntryDate 
From TableName 
Where Slug = @slug 
    AND EntryDate BETWEEN CAST(CAST(@EntryYear AS VARCHAR(4) + CAST(@EntryMonth AS VARCHAR(2)) + '01' AS DATE) AND DATEADD(mm, 1, CAST(CAST(@EntryYear AS VARCHAR(4) + CAST(@EntryMonth AS VARCHAR(2)) + '01' AS DATE)) 

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

0

Вы пробовали просто добавить некластеризованный индекс в entrydate, чтобы узнать, какое увеличение производительности вы получите?

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

+0

Нет, я не пробовал добавлять некластеризованный индекс в EntryDate. Данные, вставленные из back-end, поэтому производительность для вставки для меня не большая. Кроме того, EntryDate не всегда является датой ее вставки. Это может быть прошлая дата. Конечный пользователь выбирает дату. –

0

Вы хотите сохранить идентификатор в виде кластерного индекса, поскольку, скорее всего, вы присоединитесь к таблице с вашего идентификатора, а не к дате ввода.

Простой некрупный индекс с только поле даты будет в порядке, чтобы ускорить процесс.

0

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

Это быстрее с большим количеством данных, но медленнее с меньшими наборами данных.

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

+0

В моем примере я добавил столбец «Slug» для решения проблем производительности для выбора отдельной конкретной записи. Можете ли вы посмотреть? Благодарю. –

+0

Было бы неплохо сделать связанное slugiD, slugName и использовать id. Поиск в текстовых полях медленный. –

0

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

Прежде всего, вам нужно выяснить, в чем заключается план запроса, почему ваши текущие запросы медленны. Без этого, это, в основном, неактуальная спекуляция (которая, как правило, контрпродуктивна при оптимизации запросов.)

Я бы ни за что не попробовал (предложенный мной или кем-либо еще) без наличия твердого запроса запроса для сравнения с ним, по крайней мере, «творить добро или зло.

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

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