Чи є спосіб визначити, чи запити SQL Server виконуються в пам'яті чи збираються на диск?


13

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

Здається досить очевидним, що продуктивність не враховувалася під час написання цих процедур, є кілька прикладів речей, які просто "не є хорошою ідеєю".

Обробка кожного рядка під час імпорту даних займає 300 мс на рядок, тому відносно невеликий імпорт займає декілька хвилин.

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

Я намагаюся визначити .... для цього, очевидно, неефективного коду, наскільки це реально впливає? Чи варто це виправити?

Отже, питання:
- чи є спосіб визначити, які таблиці повністю закріплені в пам'яті?
- чи є спосіб увімкнути трасування, щоб відстежувати вкладені збережені процедури, щоб знайти особливо дорогі частини?

Примітка. Це на SQL Server 2008 R2

Відповіді:


12

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

SELECT  DB_NAME(st.dbid) Db,
        OBJECT_NAME(st.objectid, st.dbid) Prc,
        qs.execution_count,
        qs.total_logical_reads,
        qs.total_physical_reads,
        qs.statement_start_offset,
        qs.statement_end_offset,
        st.text
FROM    sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st;

SELECT  DB_NAME(database_id) Db,
        OBJECT_NAME(object_id, database_id) Prc,
        execution_count,
        total_logical_reads,
        total_physical_reads
FROM    sys.dm_exec_procedure_stats ps;

Перший розбиває це на висловлювання, другий вважає за всю процедуру.

Фізичні читання - це зчитування з диска, логічні - проти пам'яті. Ви можете використовувати це для того, щоб визначити, які процедури чи заяви найдорожчі у вашій системі, і спробувати їх налаштувати.

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

У версії DMV є багато додаткових стовпців, які також можуть вам бути цікавими.


Як індекс допомагає зменшити логічні зчитування?

У SQL Server усі дані впорядковані в блоки, розміром 8 КБ. Ці блоки називаються "сторінки".

Кожна таблиця містить "мета" сторінки, що містять інформацію про структури таблиці, а також сторінки пати. Якщо індексу немає, і ви запускаєте запит, наприклад, що SELECT * FROM tbl WHERE Id = 7SQL Server повинен шукати ту чи ці рядки у всій таблиці. Таким чином, він читається по одній сторінці по черзі, перебирає всі рядки на кожній сторінці, щоб визначити рядки, які відповідають WHEREпідпункту. Отже, якщо в таблиці потрібно зберігати 1 000 000 сторінок, для цього запиту потрібно виконати 1 000 000 логічних зчитувань.

Якщо у вас є індекс, SQL Server логічно сортує дані на сторінках і встановлює зв'язаний список між сторінками. Це дозволяє виконувати запити з a ORDER BYбез виконання дорогої операції сортування. Але важливо, що сортування, SQL Server додає до таблиці B + дерево . Дерево B + - це структура, порівнянна з індексом книги, де пошук конкретного ключового слова дозволяє мені безпосередньо перейти на сторінку, що містить ключове слово. Типова книга має лише один рівень індексу, тоді як дерево B + може мати декілька. Подумайте лише про велику книгу, де сам індекс - кілька сторінок. У такому випадку має сенс додати додатковий індексний шар, який повідомляє нам, на якій сторінці Sслід знайти індексні слова, починаючи з цього.

B + Дерева оптимізовані так, щоб вони мали якомога менше рівнів, забезпечуючи властивість, що будь-який запис у індексі можна знайти, прочитавши одну сторінку за рівнем індексу. Тому припустіть вищезазначений WHERE Id = 7запит, коли у вас індекс відсортований Id. Скажімо, індекс має 5 рівнів. Тепер, щоб знайти всі записи, що відповідають цьому запиту, я повинен прочитати одну сторінку на рівні індексу (тобто 5 сторінок). Це називається "Шукати індекс". Якщо є кілька записів, які відповідають рахунку, мені, можливо, доведеться деякий час слідувати відсортованому індексу, щоб отримати їх усі. Але припустимо, що існує лише один запис.

Отже, без виконання індексу для цього запиту було потрібно 1000 000 прочитаних, а для індексу потрібно 5 зчитування. Навіть незважаючи на те, що логічне зчитування є операцією в пам'яті, це значна істотна вартість - адже це найдорожча операція в тривіальному запиті, як вище. Таким чином, зменшення кількості логічних зчитувань, необхідних в 200 000 разів, пришвидшить ваш запит аналогічним фактором.

Так, логічне зчитування не еквівалентне скануванню таблиці, але сканування таблиці викликає набагато більше логічних зчитувань, ніж пошук індексу.


> "... зменшення їх кількості (наприклад, додавши відповідний індекс) може зробити ваші запити набагато швидшими." Чи можете ви пояснити, як додавання індексу зменшить (?) Логічні читання? Чи логічне читання синонімом сканування таблиці?

1
Додано пояснення до моєї відповіді вище.
Себастьян Мейн

Спасибі. Навіть якщо припустити, що відповідні індекси є у всіх задіяних таблицях ... Я б подумав, що все ще існує велика різниця в продуктивності між таблицею, яка закріплена в пам'яті, та зчитується з диска (припустимо, однакові індекси в обох сценаріях) ... або в інших слова, додаючи індекси, ви отримаєте менший відсоток підвищення продуктивності на машині з великою кількістю оперативної пам’яті, ніж на машині з меншою пам’яттю .... правильно?

1
фізичний доступ до диска очевидно на порядок дорожчий, ніж доступ до пам'яті. Тож вжиття заходів, щоб уникнути цього, дасть вам дуже далеко. Ви все ще повинні спочатку переглянути кількість логічних зчитувань під час налаштування запитів. Утримуючи їх низькими, у свою чергу, фізичні показники будуть низькими. Також існує велика ймовірність того, що сторінки не доведеться вилучати з кешу, зменшуючи необхідні фізичні читання ще більше.
Себастьян Мейн

2
Незначна нітпік - я думаю, що сторінки - 8 кб :-). Гарна відповідь.
onupdatecascade

3
  • чи є спосіб увімкнути трасування з метою відстеження вкладених збережених процедур, щоб знайти особливо дорогі частини?

Ви можете використовувати SQL Profiler. Коли ви починаєте трасування, слід вибрати RPC Completed, SP Starting, SP StmtStarting та SP StmtCompleted (див. Зображення нижче)

введіть тут опис зображення

Це дозволить вам бачити кожен запит, який виконується всередині збережених процедур. Це дозволить вам побачити, скільки разів викликається вкладена збережена процедура. Коли слід закінчиться, слід зберегти його. Потім знову відкрийте його, і після цього ви зможете провести фільтрацію (за допомогою кнопки «Фільтри стовпців»), щоб знайти запити, які викликають у вас проблеми. (напр .: запити, що зайняли більше x прочитань або тривали більше x секунд (тривалість) ...)

Параметри профілера, які я вам показав, також показують план виконання, який також дуже допомагає.


1

Це здається загальним питанням оптимізації запитів. З вашого опису я:

  1. Подивіться на код, щоб побачити, чи обробляє він по черзі. Якщо це так, то часто можна навести порядки на величину, реалізуючи ту саму логіку за допомогою наборів (декілька рядків, оброблених одночасно). Іншими словами, якщо він діє як "петля над кожним рядком", змініть його на "обробити всі рядки". SQL в цьому перевершує те, що оптимізатор може вибирати з більш можливих методів, потенційно використовувати паралелізм, видаляти багато накладних витрат, що надходять з одного ряду одночасно.
  2. Далі переконайтеся, що є індекси, які підтримують роботу. Часто, знову ж таки, порядки покращення масштабів можуть мати правильні показники порівняно з ні. Це вірно в пам'яті та з доступом до диска. Процеси все ще можуть займати години зі всією оперативною пам’яттю, якщо у великому наборі даних немає відповідних індексів.
  3. Далі, встановивши встановлені логіку та індекси, я би роздивився, чи впадають у пам'ять сторінки, що стосуються даних. На даний момент, якщо доступу до диска все ще багато, перегляд фізичних зчитувань та активності диска має сенс, оскільки всі великі вигоди від оптимізації робляться в перші два кроки.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.