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

15

Этот вопрос касается производительности индекса SQL Server со varchar(2000)встроенным INCLUDEиндексом.

Я пытаюсь улучшить производительность в медленном и нестабильном приложении базы данных. В некоторых случаях доступ к данным осуществляется через большие строки VARCHAR, с запросами , включая multple строковых операций , как SUBSTRING(), SPACE(), и DATALENGTH(). Вот упрощенный пример доступа;

update fattable set col3 =  
   SUBSTRING(col3,1,10) + '*' + 
   SUBSTRING(col3,12,DATALENGTH(col3)-12)
from fattable where substring(col3,10,1) = 'A' and col2 = 2

Схема выглядит следующим образом:

CREATE TABLE [dbo].[FatTable]( 
    [id] [bigint] IDENTITY(1,1) NOT NULL, 
    [col1] [nchar](12) NOT NULL, 
    [col2] [int] NOT NULL, 
    [col3] [varchar](2000) NOT NULL, ... 

Определен следующий индекс с полем покрытия в большом текстовом столбце.

CREATE NONCLUSTERED INDEX [IndexCol2Col3] ON [dbo].[FatTable]  ( [col2] ASC ) 
    INCLUDE( [col3] )

Из того, что я прочитал, ПЛОХО помещать большие поля данных в индекс. Я читал несколько статей, в том числе http://msdn.microsoft.com/en-us/library/ms190806.aspx, в которых обсуждается влияние подкачки и размера диска на производительность индекса. При этом план запроса определенно использует индекс покрытия. У меня недостаточно информации, чтобы определить, сколько это на самом деле стоит мне с точки зрения загрузки системы. Я знаю, что в целом система работает плохо, и я обеспокоен тем, что это одна из проблем. Вопросов:

  • Является ли эта varchar(2000)колонка в индексе INCLUDEхорошей идеей?

  • Поскольку INCLUDEполя хранятся в конечных узлах, сильно ли они влияют на производительность индекса?

Обновление: спасибо за отличные ответы! В некотором смысле это несправедливый вопрос - как вы, ребята, говорите, что нет абсолютно правильного ответа без реальной статистики и профилирования. Как и многие другие проблемы с производительностью, я думаю, что ответ "это зависит".

RaoulRubin
источник
Как долго действительные значения? A, VARCHAR(2000)который обычно хранит только десять символов, это одно; твердые 2000 байтов на запись - это нечто другое.
Джон на все руки
Просто замечание: что-то, что «пахнет» здесь, это то, что большой столбец может содержать либо 1) свободный текст, в этом случае запросы могут выиграть от переписывания с использованием индекса FULLTEXT или 2) «читаемых человеком» кодированных данных (например, широкий интеллектуальный ключи, такие как VIN), которые могли бы выиграть от разделения на отдельные столбцы или постоянные вычисляемые столбцы с индексами. Другими словами, поток информации и изменений данных не разработан должным образом.
Грэм
1
Да # Грэм, здесь есть неприятный запах - я думаю, что это называется "наследие". В этих базах данных множество проблем.
РаульРубин

Ответы:

14

Это большое слово, но в общем нет, я бы не поместил поле varchar (2000) в INCLUDE.

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

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

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

Грант Фричей
источник
Спасибо, Грант. Как я уже упоминал в другом комментарии, хорошей информации о производительности мало, отсюда и абстрактный вопрос. У меня нет опыта мониторинга затрат на размер страницы. Я догадываюсь, что это проблема, посмотрим, смогу ли я получить статистику.
RaoulRubin
1
Включение статистики ввода-вывода для запроса скажет вам многое, логическое чтение представляет количество страниц, к которым обращались. Вы также можете следить за секундами / считыванием счетчиков perfmon, чтобы получить общую информацию о производительности.
Грант Фричей
6

Можете ли вы просмотреть текущий ключ кластеризованного индекса и, возможно, col2вместо этого создать ключ кластеризованного индекса? Таким образом, вы получаете скрытое поведение «включить» (поскольку кластеризованные индексы всегда «включают» все) без дублирования данных. Это, конечно, зависит от многих ifи but, тем не менее, возможно, стоит рассмотреть. Конечно, если текущий кластеризованный индекс применяет ограничение (первичный ключ, уникальный), указанное ограничение необходимо будет перенести в некластеризованный индекс.

Ремус Русану
источник
Ваше предложение по поводу PK - отличная идея, хотя я не смогу применить его в этом случае - существующий PK необходим для других запросов. (Это техника, которую я буду держать в наборе инструментов!)
RaoulRubin
4

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

Аарон Бертран
источник
В целом чтение и обновление в основном сбалансированы. Организационные проблемы и вопросы конфиденциальности затрудняют получение полезной статистики и реалистичных тестов. Поскольку мы летим в основном вслепую, мы должны смотреть на вещи с абстрактной точки зрения (отсюда и этот вопрос). Тестирование будет означать толчок изменений в производстве и наблюдение за результатами - очень рискованно.
RaoulRubin
2
И действительно ли большинство операций чтения вытягивают этот VARCHAR(2000)столбец, или вы устраняете неполадки с производительностью очень конкретного запроса, который не соответствует большинству запросов? Как предполагает Грант, если этот столбец не используется во многих запросах или действительно вызывает проблемы при поиске, вероятно, будет лучше заплатить цену за поиск, когда вам это нужно, но не платить за хранение, когда вы этого не сделаете. , Опять же, очень трудно сказать, на какой стороне забора вы должны быть, потому что у нас на самом деле нет никакой специфики (и даже сложнее, потому что вы не можете проверить - вы должны стремиться это исправить).
Аарон Бертран
3

Я знаю, что опаздываю на эту вечеринку, но я бы проиндексировал именно те выражения, которые использовались для поиска строк, например, подстрока (col3,10,1). Если бы когда-либо использовался весь col3, я бы индексировал CHECKSUM (col3) (конечно, понимая, что могут быть коллизии).

Аляска
источник