Как повысить производительность таблицы SQL Server с полями изображений?

StackOverflow https://stackoverflow.com/questions/2253582

Вопрос

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

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

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

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

SELECT TOP 100 *
  FROM OFFENDING_TABLE

Получение данных в анализаторе запросов занимает 30 секунд.

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

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

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

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


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

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

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

Это было полезно?

Решение

Я бы порекомендовал вам ознакомиться с нарушающим здоровье макетом таблицы:

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 секунд на ожидание блокировки строки.Посмотрите на системные запросы dm_exec_requests во время выполнения запроса смотрите wait_time, wait_type и wait_resource.Это PAGEIOLATCH_XX?Или это замок?Кроме того, как sys.dm_os_wait_stats система.dm_os_wait_stats каковы основные причины ожидания на вашем сервере?

Другие советы

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

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

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

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

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

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

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

Короткий ответ заключается в том, чтобы выполнять выборку только для нескольких строк, когда возвращаемые поля не включают поле оскорбительного изображения, т. Е. нет ВЫБОРА *.Если вам нужно значение поля image, извлекайте его в каждом конкретном случае.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top