Внезапное снижение производительности SQL Server

13

У меня есть SQL Server 2005, который стал непредсказуемым в последнее время, и я ломаю голову над тем, почему. Запросы, которые выполняются за считанные секунды, меняют планы и занимают минуты (время, затрачиваемое на полное сканирование таблицы или спулинг индекса). Теперь первая и самая очевидная вещь - статистика устарела, что приводит к замешательству оптимизатора, но я убежден, что это не так - во-первых, потому что базовые данные существенно не меняются (например, добавление данных за день поверх данных за год уже в таблице) и, во-вторых, потому что значения «Автоматическое создание статистики» и «Автоматическое обновление статистики» являются истинными Однако оптимизатор будет путаться; Запуск SQL в Tuning Advisor дает мне много многостолбцовых CREATE STATISTICSоператоров, которые, кажется, это исправляют (до тех пор, пока следующий бит SQL не будет себя вести).

Любые идеи стратегии, которую я могу использовать, чтобы приблизиться к первопричиной этого? Любой, почему «нормальной» статистики недостаточно?

Gaius
источник

Ответы:

8

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

Как оформляются ваши запросы? Это динамический SQL? Вы используете хранимые процедуры? Вы используете sp_executesql? Возможно ли, что у вас есть случай перехвата параметров? Как выглядит ваш дизайн БД? Каковы отношения PK и FK?

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

Можете ли вы привести пример плохого плана?

И наконец, возьмите копию sp_whoIsActive ( http://whoisactive.com/ ) от Адама Маханича и используйте ее, чтобы узнать больше о выполняющихся запросах. И если вы хотите иметь возможность получить выходные данные из sp_whoIsActive, перейдите сюда http://www.littlekendra.com/2011/02/01/whoisactive/

SQLRockstar
источник
Это стороннее приложение, я не имею никакого контроля над его схемой или SQL, что довольно ужасно, множество параметризованных запросов (например where col=(cast @var...)) и @varможет быть '%'. Я унаследовал это неделю или две назад, и мне нужно, чтобы он работал в основном до тех пор, пока он не будет заменен. Спасибо за ссылку, я приведу ее в движение.
Гай
Следующее самое большое ожидание SOS_SCHEDULER_YIELDбыло, CXPACKETи, sp_configure "max degree of parallelism", 1похоже, пока что выбило обе проблемы из головы. Благодарность!
Гай
+1 за ссылку на sp_whoIsActive
Джефф
8

Из MSDN :

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

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

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

Вы можете время от времени использовать «EXEC sp_updatestats» в вашей системе (запланировано некоторое время) или использовать функцию STATS_DATE для всех объектов и посмотреть, когда их статистика действительно обновлялась в последний раз, и с тех пор было слишком много времени, используйте UPDATE. СТАТИСТИКА для этого конкретного объекта. По моему опыту, даже при включенной автоматической статистике мы все равно вынуждены время от времени обновлять статистику из-за операций вставки, которые не запускали автоматическое обновление.

Чтобы добавить мой личный код (используется в еженедельной работе, которая создает динамические отчеты для обновления статистики):

select distinct
        'update statistics [' + stats.SchemaName + '].[' + stats.TableName + ']'
            + case when stats.RowCnt > 50000 then ' with sample 30 percent;'
            else 
                ';' end
        as UpdateStatement
    from (
        select
            ss.name SchemaName,
            so.name TableName,
            so.id ObjectId,
            st.name AS StatsName, 
            STATS_DATE(st.object_id, st.stats_id) AS LastStatisticsUpdateDate
            , si.RowModCtr
            , (select case si2.RowCnt when 0 then 1 else si2.RowCnt end from sysindexes si2 where si2.id = si.id and si2.indid in (0,1)) RowCnt
        from sys.stats st
            join sysindexes si on st.object_id = si.id and st.stats_id = si.indid
            join sysobjects so on so.id = si.id and so.xtype = 'U' --user table
            join sys.schemas ss on ss.schema_id = so.uid
    ) stats
    where cast(stats.RowModCtr as float)/cast(stats.RowCnt as FLOAT)*100 >= 10 --more than 10% of the rows have changed
    or ( --update statistics that were not updated for more than 3 months (and rows no > 0)
        datediff(month, stats.LastStatisticsUpdateDate, getdate()) >= 3
        and stats.RowCnt > 0
    )

Здесь я получаю все объекты, у которых статистика не обновлялась более 3 месяцев или с момента последнего обновления статистики изменилось более 10% строк.

Мэриан
источник
Хм, мое главное событие ожидания, SOS_SCHEDULER_YIELDно я не могу сказать прямо сейчас, если это из-за плохих планов, или что этот (6-летний, 2-процессорный, 4G RAM) ящик действительно только что перегружен, и я прошли через переломный момент.
Гай
вместо того, чтобы просто выполнять этот запрос для создания операторов UPDATE и запускать их вручную, вы можете использовать курсор на основе этого оператора select для циклического округления результатов, запускающих их с использованием вызовов sp_executesql - таким образом, вы можете запускать его автоматически (например, как часть плана обслуживания на ночь (или другой тихий период).
Дэвид Спиллетт
@ Дэвид: это то, что я делаю в еженедельной работе :). Я просто отформатировал его по-другому, чтобы Гай увидел результат, который я использую. Первоначальный сценарий был слишком уродливым и длинным. Спасибо за помощь с форматированием! Можете ли вы отправить меня на учебник по форматированию ... потому что я действительно не знаю, как сделать код выглядит здесь хорошо. Благодарность!
Marian
На экране «Редактировать ответ» есть ссылка «Справка по форматированию», а в виде значка справа над начальным полем ответа на главной странице вопроса указывается синтаксис уценки, поддерживаемый этими сайтами.
Дэвид Спиллетт
3
Автоматическое обновление статистики на самом деле срабатывает при 20% + 500 строк, а не 10%.
Мрденный
3

Я предполагаю, что одна или несколько ваших таблиц становятся достаточно большими, чтобы не превышать 20% изменений, необходимых, чтобы пометить текущую статистику как устаревшую, чтобы сработала статистика автоматического обновления, и при этом было достаточно обновлений (или вставок). ) что обновление статистики очень помогло бы. Недавно я обнаружил то же самое в конкретной среде после обновления с SQL 2000 до SQL 2008.

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

1) Red-Gate имеет ряд бесплатных электронных книг, доступных для скачивания, включая «Статистика SQL Server» Хольгера Шмелинга, где вы найдете следующую цитату:

http://www.red-gate.com/our-company/about/book-store/

«Таблицы с более чем 500 строками, по крайней мере, 20% данных столбца должны были быть изменены, чтобы сделать недействительной любую связанную статистику»

2) SQL Sentry имеет бесплатный инструмент Plan Explorer, который помогает отследить проблемы в плане SQL, такие как оценка слишком большого или слишком малого количества строк по сравнению с фактическим количеством строк для данной таблицы в запросе. Просто сохраните фактический план выполнения из SSMS, а затем пройдитесь по различным частям плана с помощью Plan Explorer. Дело не в том, что информация недоступна в SSMS с использованием графического плана выполнения, но инструмент из SQL Sentry делает его намного проще для просмотра.

http://www.sqlsentry.com/plan-explorer/sql-server-query-view.asp

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

http://blog.sqlauthority.com/2010/01/25/sql-server-find-statistics-update-date-update-statistics/

Надеюсь, это поможет!

Я думаю, вам особенно понравится книга от Red-Gate!

-Джефф

Джефф
источник
Спасибо, я проработаю их. В основном я являюсь администратором базы данных Oracle, унаследовавшим эту систему (хотя я вообще не предубежден против SQL Server, поскольку с 2005 года я вижу, что это очень способная платформа, я просто не знаю ее так же хорошо, как Oracle) ,
Гай