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

Изрязване на мазнини в дневника на транзакциите

В много работни натоварвания на SQL Server, особено OLTP, регистърът на транзакциите на базата данни може да бъде пречка, която увеличава времето, необходимо за завършване на транзакцията. Повечето хора приемат, че I/O подсистемата е истинското тесно място, тъй като не може да се справи с количеството регистрационен файл на транзакциите, генериран от натоварването.

Закъснение при запис на дневник на транзакциите

Закъснението на операциите на запис в регистрационния файл на транзакциите може да се наблюдава с помощта на sys.dm_io_virtual_file_stats DMV и корелира с WRITELOG изчаквания, които се случват в системата. Записах демонстрационно видео за анализиране на I/O дневника на транзакциите през 2011 г., така че няма да повтарям всичко това в тази публикация. Можете да получите видеоклипа тук и демонстрационния код тук (подходящ за стартиране в производството веднага).

Ако латентността при запис е по-висока, отколкото бихте очаквали за вашата I/O подсистема, тогава I/O подсистемата не може да се справи, както е общото предположение. Това означава ли, че I/O подсистемата трябва да бъде подобрена? Не е задължително.

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

Има две основни причини за генериране на външни регистрационни записи:неизползвани неклъстерирани индекси и фрагментиране на индекси.

Неизползвани неклъстерирани индекси

Всеки път, когато запис се вмъкне в таблица, запис трябва да бъде вмъкнат във всеки неклъстериран индекс, дефиниран в таблицата (с изключение на филтрирани индекси с подходящи филтри, които ще игнорирам от този момент). Това означава, че се генерират допълнителни регистрационни записи, поне по един на неклъстериран индекс, за всяко вмъкване на таблица. Същото важи и за изтриването на запис в таблица – съвпадащите записи трябва да бъдат изтрити от всички неклъстерирани индекси. За актуализация на запис на таблица, неклъстерираните индексни записи се актуализират само ако неклъстерираните индексни ключови колони или включените колони(и) са били част от актуализацията.

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

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

Откъдето и да идват, неизползваните индекси трябва да бъдат премахнати, за да се намалят разходите им. Можете да определите кои индекси са неизползвани с помощта на sys.dm_db_index_usage_stats DMV и ви препоръчвам да прочетете публикациите на моите колеги Кимбърли Л. Трип (тук) и Джо Сак (тук и тук), тъй като те обясняват как да използвате правилно DMV.

Фрагментация на индекса

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

Фрагментацията се причинява от операция, наречена разделяне на страница. Най-простата причина за разделяне на страница е, когато индексен запис трябва да бъде вмъкнат на конкретна страница (поради нейната ключова стойност) и страницата няма достатъчно свободно място. В този сценарий ще се извършат следните операции:

  • Нова индексна страница е разпределена и форматирана
  • Някои от записите от цялата страница се преместват на новата страница, като по този начин се създава свободно място в необходимата страница
  • Новата страница е свързана към структурата на индекса
  • Новият запис е вмъкнат на необходимата страница

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

Първата стъпка за намаляване на допълнителните разходи е да премахнете неизползваните индекси, както описах по-горе, така че да не генерират разделяне на страници. Втората стъпка е да се идентифицират останалите индекси, които стават фрагментирани (и затова трябва да страдат от разделяне на страници) с помощта на sys.dm_db_index_physical_stats DMV (или новия SQL Sentry Fragmentation Manager) и проактивно създаване на свободно пространство в тях с помощта на индекс запълване. Факторът за запълване инструктира SQL Server да оставя празно място на индексните страници, когато индексът е изграден, преустроен или реорганизиран, така че да има място, което да позволи вмъкване на нови записи, без да се изисква разделяне на страницата, като по този начин се намаляват генерираните допълнителни записи в дневника.

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

Резюме

Намаляването на латентността при запис на регистрационен файл на транзакциите не винаги означава преминаване към по-бърза I/O подсистема или разделяне на файла в собствена част от I/O подсистемата. С някакъв прост анализ на индексите във вашата база данни може да сте в състояние значително да намалите количеството генерирани записи в дневника на транзакциите, което води до съизмеримо намаляване на латентността при запис.

Има и други, по-фини проблеми, които могат да повлияят на ефективността на регистрационния файл на транзакциите и ще ги разгледам в следваща публикация.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Цели на редове, част 4:Моделът срещу анти присъединяване

  2. Размер на извадката и продължителност на АКТУАЛИЗИРАНЕ НА СТАТИСТИКАТА:Има ли значение?

  3. Как да добавя колона в таблица в SQL?

  4. Вашето окончателно ръководство за SQL присъединяване:КРЪСТО ПРИСЪЕДИНЯВАНЕ – част 3

  5. SQL IN срещу SQL СЪЩЕСТВУВА