Стратегии проверки ISNULL на varbinary fields?

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

select top 100 * from Files where Content is null

Я бы заподозрил, что он медленный, потому что он

  • Нужно вытащить весь двоичный файл и
  • Он не индексируется (varbinary не может быть частью нормального индекса)

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

Одним из возможных решений, о которых я думал, является создание индексированного вычисленного столбца:

alter table Files
add ContentLength as ISNULL(DATALENGTH(Content),0) persisted

CREATE NONCLUSTERED INDEX [IX_Files_ContentLength] ON [dbo].[Files] 
(
    [ContentLength] ASC
)

select top 100 * from Files where ContentLength = 0

Является ли это действующей стратегией? Какие еще существуют способы эффективного запроса при использовании двоичных полей?

Ответ 1

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

Однако вместо этого я использовал бы ISNULL(DATALENGTH(Content), -1), чтобы вы могли различать длину 0 и NULL. Или просто используйте DATALENGTH(Content). Я имею в виду, что Microsoft SQL Server не является Oracle, где пустая строка такая же, как NULL.

Ответ 2

У нас была аналогичная проблема при поиске строк, где значение varbinary не было null. Для нас было решение обновить статистику для базы данных:

exec sp_updatestats

После этого запросы выполнялись намного быстрее.