Как повысить производительность в таблице SQL Server с полями изображения? - PullRequest
6 голосов
/ 12 февраля 2010

У меня очень специфическая проблема с производительностью на работе!

В системе, которую мы используем, есть таблица, которая содержит информацию о текущем процессе работы. В одном из полей содержится электронная таблица, содержащая метаданные о процессе (не спрашивайте меня, почему !! И НЕТ, Я НЕ МОГУ ЕГО ИЗМЕНИТЬ !!)

Проблема заключается в том, что эта электронная таблица хранится в поле IMAGE в SQL Server 2005 (в базе данных, настроенной на совместимость с SQL 2000).

Эта таблица в настоящее время содержит 22K + строк и даже простой запрос, подобный этому:

SELECT TOP 100 *
  FROM OFFENDING_TABLE

Требуется 30 секунд для извлечения данных в Query Analyzer.

Я думаю об обновлении совместимости до SQL 2005 (как только мне сообщили, что приложение может с этим справиться).

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

Еще одна вещь, которую я рассматриваю, - это использовать sp_tableoption для установки large value types out of row на 1, поскольку в настоящее время 0, но у меня нет информации, если это повысит производительность.

Кто-нибудь знает, как улучшить производительность в таком сценарии?


Отредактировано для уточнения

Моя проблема в том, что у меня нет контроля над тем, что приложение запрашивает у SQL Server, и я сделал некоторые размышления над ним (приложение представляет собой веб-сайт .NET 1.1), и оно использует поле с ошибками для некоторых внутренних вещей, которые понятия не имею, что это такое.

Мне нужно улучшить общую производительность этой таблицы.

Ответы [ 4 ]

4 голосов
/ 12 февраля 2010

Я бы порекомендовал вам посмотреть на исправность таблицы:

select * from sys.dm_db_index_physical_stats(
       db_id(), object_id('offending_table'), null, null, detailed);

Также нужно поискать: avg_fragmentation_in_percent, page_count, avg_page_space_used_in_percent, record_count и ghost_record_count. Такие сигналы, как высокая фрагментация, или большое количество записей-призраков, или низкий процент использования страницы, указывают на проблемы, и вещи можно немного улучшить, просто перестроив индекс (т. Е. Таблицу) с нуля:

ALTER INDEX ALL ON offending_table REBUILD;

Я говорю это, учитывая, что вы не можете изменить ни таблицу, ни приложение. Если вы сможете изменить таблицу и приложение, совет, который вы уже получили, - это хороший совет (не используйте '*', не выбирайте без условия, используйте более новый тип varbinary (max) и т. Д. И т. Д.) .

Я бы также посмотрел на среднее время жизни страницы в счетчиках производительности, чтобы понять, не хватает ли памяти системы. Из вашего описания симптомов система выглядит связанной с вводом-выводом, что заставляет меня думать, что происходит небольшое кэширование страниц, и может помочь больше оперативной памяти, а также более быстрый подсистема ввода-вывода. В системе SQL 2008 я бы также предложил включить сжатие страниц, но в 2005 году это невозможно.
И, просто чтобы быть уверенным, убедитесь, что запросы не заблокированы конфликтом со стороны самого приложения, т.е. запрос не тратит 90% из этих 30 секунд на ожидание блокировки строки. Посмотрите sys.dm_exec_requests во время выполнения запроса, посмотрите wait_time, wait_type и wait_resource. Это PAGEIOLATCH_XX? Или это замок? Кроме того, каковы sys.dm_os_wait_stats на вашем сервере, каковы основные причины ожидания?

2 голосов
/ 12 февраля 2010

Прежде всего - никогда не делайте SELECT * в производственном коде - отчеты или нет.

У вас есть три основных варианта:

  • переместить это поле BLOB-объекта в отдельную таблицу, если оно не всегда необходимо; вероятно, не практично, так как вы упоминаете, что не можете изменить схему

  • будьте осторожнее с вашими SELECT инструкциями, чтобы выбрать только те поля, которые вам действительно нужны - и пропустите поле blob

  • посмотрите, можете ли вы ограничить свой запрос включением предложения WHERE и найти способ оптимизировать план запроса, например, например. добавление подходящего индекса в таблицу (если вы можете)

Нет волшебного переключателя "сделай это быстрее" - но ты можешь оптимизировать свой запрос или оптимизировать макет таблицы. Оба помогают. Если вы ничего не можете изменить - ни макет таблицы, ни добавление индекса, ни изменение запросов, я боюсь, вам будет сложно оптимизировать что-либо, боюсь ...

Простое изменение поля на VARBINARY (MAX) ничего не изменит - никакого улучшения производительности ожидать не следует только от изменения типа данных.

1 голос
/ 12 февраля 2010

Короткий ответ - делать SELECT только для нескольких строк, когда возвращаемые поля не содержат поле изображения, которое нарушает работу, т. Е. Нет SELECT *. Если вам нужно значение поля изображения, извлекайте его в каждом конкретном случае.

0 голосов
/ 12 февраля 2010

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

...