Database
 sql >> база данни >  >> RDS >> Database

Проследяване на актуализации на синхронни статистически данни

Въведение

Оптимизаторът на заявки на SQL Server използва статистически данни по време на компилацията на заявки, за да помогне за определяне на оптималния план за заявка. По подразбиране, ако оптимизаторът забележи, че дадена статистика е остаряла поради твърде много промени в таблица, той ще актуализира статистическите данни непосредствено преди компилацията на заявката да продължи (само статистическите данни, от които се нуждае, а не всички статистически данни за таблицата) .

Обърнете внимание, че „твърде много“ е неспецифично, тъй като варира в зависимост от версията и дали флагът за проследяване 2371 е активиран – вижте секцията AUTO_UPDATE_STATISTICS на тази страница за подробности.

Проблемът със синхронните актуализации на статистиката

Синхронното актуализиране на статистически данни преди компилацията очевидно води до забавяне и прави заявката да отнеме повече време за компилиране и изпълнение. Колко голямо закъснение зависи от няколко фактора, включително:

  • Колко таблици, включени в заявката, са достигнали прага „твърде много промени“
  • Колко статистики за всяка от тези таблици трябва да бъдат актуализирани, защото са необходими за компилиране
  • Колко реда има в участващите таблици
  • Опциите, посочени при създаването на всяка статистика (напр. FULLSCAN и PERSIST_SAMPLE_PERCENT=ON)

Така че може да има привидно произволно забавяне, което може да причини проблеми в някои сценарии, особено ако дадено приложение има зададено много ниско време за изчакване на заявка.

Избягване на актуализации на синхронна статистика

Има различни начини за избягване на синхронни актуализации на статистиката, като например:

  • Задаване на AUTO_UPDATE_STATISTICS на OFF, което изключва всички автоматични актуализации и означава, че ще трябва да извършвате собствена поддръжка на статистически данни, за да избегнете възможността за неоптимални планове за заявки от остарели статистически данни.
  • Задаване на AUTO_UPDATE_STATISTICS_ASYNC на ON, така че когато оптимизаторът забележи, че статистически данни трябва да бъдат актуализирани, той продължава с компилацията, а фонова задача актуализира статистиката малко по-късно. Това работи само ако имате AUTO_UPDATE_STATISTICS, зададено на ВКЛ.
  • Извършвайте редовна поддръжка на статистическите данни, така че автоматичното синхронно или асинхронно актуализиране на статистическите данни изобщо да не се случва.

В общността на SQL Server има много дебати относно това дали да се активират асинхронни актуализации на статистиката. Попитах моята прекрасна съпруга, Кимбърли Л. Трип, какво е нейното мнение и тя винаги препоръчва да го активирате, а тя е забравила повече за статистиката, отколкото някога ще знам, така че й вярвам. ☺

Проследяване на актуализации на синхронни статистически данни

Никога не е имало очевиден начин да се разбере дали дадена заявка отнема много време, защото е чакала синхронна актуализация на статистическите данни. Можете да кажете *след* актуализацията на статистиката е завършена, ако вече сте имали сесия на разширено събитие, гледайки за auto_stats събитие и филтриране на async колоната е зададена на 0. Тази колона в изхода на събитието обаче е добавена само в SQL Server 2017 и също така ще трябва да конфигурирате действие, което улавя нещо, за да идентифицира включената заявка.

Сега в SQL Server 2019 има тип на изчакване WAIT_ON_SYNCHRONOUS_STATISTICS_UPDATE и на пръв поглед изглежда, че лесно ще ви позволи да видите дали заявка чака синхронна актуализация на статистическите данни, като просто погледнете в sys.dm_os_waiting_tasks, за да видите каква е заявката в момента чакам.

За съжаление, това не е така.

Терминът „чакане“ е малко подвеждащ тук, тъй като в този случай нишката всъщност не чака. Този нов тип на изчакване е пример за това, което се нарича „превантивно“ изчакване, при което нишката преминава в режим, в който остава на процесора, докато не приключи работата си. Повечето изпреварващи изчаквания са, когато нишка извършва повикване извън SQL Server (например, за да получи информация за сигурност от контролер на домейн), но понякога нишка прави нещо вътре в SQL Server и трябва да го завърши, преди потенциално да бъде принудена да отстъпи процесора защото неговият квант на нишката от 4ms е изтекъл. Нито едно от тези неща не се случва тук. В този случай нишката регистрира началото на изпреварващо изчакване с новия тип на изчакване и след това актуализира статистиката, което вероятно води до други *реални* изчаквания като PAGEIOLATCH_SH по пътя. Едва когато актуализацията на статистическите данни приключи, изпреварващото изчакване приключва и се отчита в показателите за статистически данни за чакането.

Защо това е голяма работа? Е, DMV sys.dm_os_waiting_tasks показва типовете чакане за всички нишки, които *наистина* чакат, т.е. в списъка с чакащи задачи на планировчик, така че ако нишката за актуализиране на синхронни статистически данни не чака WAIT_ON_SYNCHRONOUS_STATISTICS type_UPDATE, това чакане тип_UPDATE няма да се появи в изхода на DMV. Новият тип чакане не може да се използва, за да се види дали заявка в момента чака актуализация на статистиката.

Можете лесно да докажете това на себе си, като направите следното:

  • Създайте таблица с няколкостотин хиляди реда
  • Създайте статистика за колона на таблицата и посочете FULLSCAN и PERSIST_SAMPLE_PERCENT =ON като опции, принуждавайки цялата таблица да се чете всеки път, когато статистиката се актуализира
  • Актуализиране на двадесет хиляди реда
  • Проверете базата данни и изпълнете DBCC DROPCLEANBUFFERS
  • Направете оператор SELECT с клауза WHERE в колоната със статистическите данни, които сте създали
  • Потърсете в sys.dm_os_waiting_tasks DMV идентификатора на сесията на SELECT и ще видите, че вероятно чака PAGEIOLATCH_SH, докато актуализацията на статистиката чете през таблицата

Като оставим това разочарование настрана, има трик, за да можете да видите дали дадена заявка чака за синхронна актуализация на статистическите данни. Когато се случи актуализация на статистическите данни, се изпълнява команда, наречена STATMAN и можете да видите това да се случва в изхода от sys.dm_exec_requests :състояние ще бъде „спряно“ (въпреки че нишката работи, както описах по-горе), а командата ще бъде „SELECT (STATMAN).“

Каква е ползата от новия тип на изчакване?

Въпреки че новият тип на изчакване не може да се използва като незабавен начин да се разбере, че заявката чака синхронна актуализация на статистическите данни, ако се появи във вашия редовен анализ на статистическите данни за чакане, знаете, че някои заявки в работното натоварване може да страдат от тези забавяния . Но това е пределът на неговата полезност, що се отнася до мен. Освен ако средното време на изчакване не се покаже като притеснителен процент от средното ви време за изпълнение на заявка или ако непрекъснато улавяте изчаквания за малки периоди от време, за да позволите правилен анализ, не знаете със сигурност дали има проблем.

Това е тип на изчакване, при който времето за изчакване може да варира значително в зависимост от факторите, които споменах по-рано. Ето защо бих използвал само наличието на този тип чакане, за да бъда предупреден за потенциални проблеми и бих искал да внедря сесия с разширено събитие, както е описано по-горе, за да заснема случаи на синхронни актуализации на статистиката, за да видя дали тяхната продължителност е достатъчно дълга, за да заслужи предприемане на някои коригиращи действия.

Резюме

Не съм сигурен, че добавянето на типа на изчакване WAIT_ON_SYNCHRONOUS_STATISTICS_UPDATE ще промени дали хората конфигурират асинхронни актуализации на статистическите данни или просто извършват цялата поддръжка на статистическите данни сами, но поне сега ще можете да разберете дали заявките чакат синхронни статистически данни актуализации и предприемете допълнителни действия.

До следващия път, щастливо отстраняване на неизправности!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Въведение в Azure без сървър

  2. Топ 115 въпроса за SQL интервю, които трябва да подготвите през 2022 г

  3. Въпроси и отговори от нашата поредица от уебинари за Параметър Sniffing

  4. Ролята на DBA в NoSQL

  5. Генериране на набор или последователност без цикли – част 1