Этот вопрос касается производительности индекса 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
поля хранятся в конечных узлах, сильно ли они влияют на производительность индекса?
Обновление: спасибо за отличные ответы! В некотором смысле это несправедливый вопрос - как вы, ребята, говорите, что нет абсолютно правильного ответа без реальной статистики и профилирования. Как и многие другие проблемы с производительностью, я думаю, что ответ "это зависит".
источник
VARCHAR(2000)
который обычно хранит только десять символов, это одно; твердые 2000 байтов на запись - это нечто другое.Ответы:
Это большое слово, но в общем нет, я бы не поместил поле varchar (2000) в INCLUDE.
И да, способ хранения данных на уровне страницы может серьезно повлиять на производительность индекса в зависимости от того, как индекс используется.
Дело в том, что чем больше строк данных вы можете втиснуть в страницу, тем меньше нужно будет получить доступ к страницам, по большей части, ваша система будет работать быстрее. Добавление действительно большого столбца означает, что на странице сохраняется меньше информации, поэтому в случае поиска или сканирования диапазона необходимо прочитать больше страниц, чтобы получить данные, что серьезно замедляет работу.
Чтобы точно знать, является ли это проблемой в вашем запросе или в вашей системе, вам необходимо отслеживать чтения, особенно количество страниц, используемых запросом.
источник
Можете ли вы просмотреть текущий ключ кластеризованного индекса и, возможно,
col2
вместо этого создать ключ кластеризованного индекса? Таким образом, вы получаете скрытое поведение «включить» (поскольку кластеризованные индексы всегда «включают» все) без дублирования данных. Это, конечно, зависит от многихif
иbut
, тем не менее, возможно, стоит рассмотреть. Конечно, если текущий кластеризованный индекс применяет ограничение (первичный ключ, уникальный), указанное ограничение необходимо будет перенести в некластеризованный индекс.источник
Сложно ответить. Все будет зависеть от вашего отношения чтения: записи. Вы тестировали рабочую нагрузку или имитировали весь бизнес-цикл в тестовой системе с включенным столбцом и без него? Поиск без него может стоить дорого, но если вы обновляете данные чаще, чем читаете, это может быть нормально.
источник
VARCHAR(2000)
столбец, или вы устраняете неполадки с производительностью очень конкретного запроса, который не соответствует большинству запросов? Как предполагает Грант, если этот столбец не используется во многих запросах или действительно вызывает проблемы при поиске, вероятно, будет лучше заплатить цену за поиск, когда вам это нужно, но не платить за хранение, когда вы этого не сделаете. , Опять же, очень трудно сказать, на какой стороне забора вы должны быть, потому что у нас на самом деле нет никакой специфики (и даже сложнее, потому что вы не можете проверить - вы должны стремиться это исправить).Я знаю, что опаздываю на эту вечеринку, но я бы проиндексировал именно те выражения, которые использовались для поиска строк, например, подстрока (col3,10,1). Если бы когда-либо использовался весь col3, я бы индексировал CHECKSUM (col3) (конечно, понимая, что могут быть коллизии).
источник