Раптова погіршення продуктивності SQL Server


13

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

Будь-які ідеї стратегії, які я можу використати для підходу до цього? Чому б «нормальної» статистики недостатньо?

Відповіді:


8

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

Як видаються ваші запити? Це динамічний SQL? Чи використовуєте ви збережені процедури? Ви використовуєте sp_executesql? Можливо, у вас є випадок обнюхування параметрів? Як виглядає ваш дизайн db? Які стосунки PK та FK?

Чи є у вас приклад хорошого плану? Якщо ви зможете визначити хороший план, ви можете скористатись посібниками щодо плану, щоб змусити запит виконувати певний спосіб.

Чи можете ви навести приклад того, що гарний план пішов погано?

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


Це стороннє додаток, я не маю контролю над його схемою або SQL, що дуже жахливо, багато параметризованих запитів (наприклад where col=(cast @var...)) і @varможливо '%'. Я просто успадкував його тиждень-два тому, і потрібно тримати його в основному, поки він не заміниться. Дякую за посилання, я дам йому кружляння.
Гай

Наступне найбільше очікування після того, як SOS_SCHEDULER_YIELDбуло, CXPACKETі, sp_configure "max degree of parallelism", 1здається, тепер побив обидві проблеми по голові. Спасибі!
Гай

+1 за посилання на sp_whoIsActive
Джефф

8

Від MSDN :

" Операції " Вставка " відбуваються на висхідних або низхідних стовпцях ключових стовпців. Збільшення або зменшення стовпців ключових значень, таких як ІДЕНТИЧНІСТЬ або стовпці часових міток у режимі реального часу, можуть вимагати більш частого оновлення статистики, ніж виконує оптимізатор запитів. . Кількість доданих рядків може бути занадто малою, щоб викликати оновлення статистики. Якщо статистика не є актуальною, а запити вибираються з останніх доданих рядків, поточна статистика не матиме оцінок кардинальності для цих нових значень. Це може приводить до неточних оцінок кардинальності та повільному виконанню запитів.

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

Після операцій технічного обслуговування Розгляньте оновлення статистичних даних після виконання процедур технічного обслуговування, що змінюють розподіл даних, наприклад, обрізання таблиці або виконання об'ємної вставки великого відсотка рядків. Це дозволяє уникнути майбутніх затримок в обробці запитів, поки запити чекають автоматичних оновлень статистики. "

Ви можете час від часу використовувати "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 оперативна пам’ять) справді просто перевантажена, і я перейшов деякий переломний момент.
Гай

замість того, щоб просто запустити цей запит для створення операторів UPDATE та запустити їх вручну, ви можете використовувати курсор на основі цього оператора select, щоб обвести результати, запускаючи їх, використовуючи виклики sp_executesql - таким чином ви можете запустити його автоматично (наприклад, як частина плану технічного обслуговування (або іншого тихого періоду).
Девід Спіллетт

@David: саме цим я займаюся на щотижневій роботі :). Я щойно відформатував його для Gaius, щоб побачити вихід, який я використовую. Початковий сценарій виявився занадто потворним і довгим. Дякуємо за допомогу з форматуванням! Чи можете ви надіслати мене до навчального посібника з форматування ... тому що я насправді не знаю, як зробити так, щоб код виглядав добре. Спасибі!
Маріан

на екрані "редагувати відповідь" є посилання "довідка щодо форматування", і як значок праворуч над початковим полем відповідей на головній сторінці запитань, у якому перерахований синтаксис розмітки, підтримуваний цими сайтами.
Девід Спіллетт

3
Статистика автоматичного оновлення насправді спрацьовує на рівні 20% + 500 рядків, а не 10%.
mrdenny

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 має безкоштовний інструмент Провідника плану, який допомагає відстежувати проблеми в плані SQL, такі як оцінка занадто багато або занадто мало рядків у порівнянні з фактичною кількістю рядків для даної таблиці в запиті. Просто збережіть фактичний план виконання від SSMS, а потім пройдіться по різних частинах плану за допомогою Провідника плану. Справа не в тому, що інформація не доступна в 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!

-Джефф


Дякую, я пророблю їх. Я в основному DBA Oracle, який успадкував цю систему (т. Е. Я взагалі не заперечую щодо SQL Server. З того, що я бачу з 2005 року, це дуже спроможна платформа, я просто не знаю її, як я знаю Oracle) .
Гай
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.