Оператор використовував tempdb для розливу даних під час виконання із рівнем 2 розливу


18

Я намагаюся мінімізувати витрати на операцію сортування в плані запитів із попереджувальним Operator usedtempdbto spill data during execution with spill level 2

Я знайшов декілька публікацій, пов’язаних із інформацією про розливи під час виконання з рівнем 1 , але не з рівнем 2. Рівень 1, здається, викликаний застарілою статистикою , а як щодо рівня 2? Я не міг знайти нічого, пов’язаного з цим level 2.

Мені ця стаття виявилася дуже цікавою, пов’язаною із сортуванням попереджень:

Ніколи не ігноруйте попередження про сортування в SQL Server

Мій сервер Sql?

Microsoft SQL Server 2014 (SP2) (KB3171021) - 12.0.5000.0 (X64) 17 червня 2016 19:14:09 Авторські права (c) Microsoft Corporation Enterprise Edition (64-розрядні) на Windows NT 6.3 (збірка 9600:) (Hypervisor)

Моє обладнання?

запустіть запит нижче, щоб знайти програмне забезпечення:

- Інформація про обладнання від SQL Server 2012

SELECT cpu_count AS [Logical CPU Count], hyperthread_ratio AS [Hyperthread Ratio],
cpu_count/hyperthread_ratio AS [Physical CPU Count], 
physical_memory_kb/1024 AS [Physical Memory (MB)], affinity_type_desc, 
virtual_machine_type_desc, sqlserver_start_time
FROM sys.dm_os_sys_info WITH (NOLOCK) OPTION (RECOMPILE);

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

На даний момент виділена пам'ять

SELECT
(physical_memory_in_use_kb/1024) AS Memory_usedby_Sqlserver_MB,
(locked_page_allocations_kb/1024) AS Locked_pages_used_Sqlserver_MB,
(total_virtual_address_space_kb/1024) AS Total_VAS_in_MB,
process_physical_memory_low,
process_virtual_memory_low
FROM sys.dm_os_process_memory;

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

коли я запускаю запит з діапазоном року, я не отримую жодного попередження, як показано на малюнку нижче:

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

Але коли я запускаю його лише протягом 1 дня, я отримую це попередження on the sort operator:

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

це запит:

    DECLARE @FromDate SMALLDATETIME = '19-OCT-2016 11:00'
    DECLARE @ToDate   SMALLDATETIME = '20-OCT-2016 12:00'




    SELECT      DISTINCT
                a.strAccountCode ,
                a.strAddressLine6 ,
                a.strPostalCode ,
                CASE    WHEN a.strCountryCode IN ('91','92') THEN 'GB-Int'
                        ELSE a.strCountryCode
                        END AS [strCountryCode]
    FROM        Bocss2.dbo.tblBAccountParticipant AS ap
    INNER JOIN  Bocss2.dbo.tblBAccountParticipantAddress AS apa ON ap.lngParticipantID = apa.lngParticipantID
                                                                AND apa.sintAddressTypeID = 2
    INNER JOIN  Bocss2.dbo.tblBAccountHolder AS ah ON ap.lngParticipantID = ah.lngParticipantID
    INNER JOIN  Bocss2.dbo.tblBAddress AS a ON apa.lngAddressID = a.lngAddressID
                                            AND a.blnIsCurrent = 1
    INNER JOIN  Bocss2.dbo.tblBOrder AS o ON ap.lngParticipantID = o.lngAccountParticipantID
                                        AND o.sdtmOrdCreated >= @FromDate
                                        AND o.sdtmOrdCreated < @ToDate

OPTION(RECOMPILE)

план запитів тут

план запитів за допомогою pastetheplan

Запитання: 1) у плані запитів я бачу це:

StatementOptmEarlyAbortReason="GoodEnoughPlanFound" CardinalityEstimationModelVersion="70" 

чому 70? Я використовую сервер sql 2014

2) як я можу позбутися цього оператора сортування (якщо це взагалі можливо)?

3) Я бачив очікуване тривалість життя сторінки досить низьким, окрім додавання більшої кількості пам’яті на цей сервер, чи є інша річ, яку я можу подивитися, чи зможу я запобігти цьому попередженню?

ура

Оновлення після відповіді Шенкі та Пола Вайт

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

це всі індекси та таблиці, що використовуються в цьому запиті.

DBCC SHOW_STATISTICS ('dbo.tblBAddress','IDXF_tblBAddress_lngAddressID__INC')
GO
DBCC SHOW_STATISTICS  ('dbo.tblBOrder','IX_tblBOrder_sdtmOrdCreated_INCL')
GO
DBCC SHOW_STATISTICS ('dbo.tblBAccountHolder','PK_tblAccountHolder')
GO
DBCC SHOW_STATISTICS ('dbo.tblBAccountParticipant','PK_tblBAccountParticipants')
GO
DBCC SHOW_STATISTICS ('dbo.tblBAccountParticipantAddress','IDXF_tblBAccountParticipantAddress_lngParticipantID')
GO

ось що мені повернули:

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

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

Це часткові результати, але я їх повторно відвідав.

Для оновлення статистики у мене зараз є Ола Галленгрен

індекс оптимізувати роботу - планується працювати раз на тиждень - неділю

EXECUTE [dbo].[IndexOptimize] 
@Databases = 'USER_DATABASES,-%Archive', 
@Indexes = 'ALL_INDEXES' , 
@FragmentationLow = NULL,
@FragmentationMedium = NULL,
@FragmentationHigh = NULL,
@PageCountLevel=1000,
@StatisticsSample =100
,@UpdateStatistics = 'Index', 
@OnlyModifiedStatistics = 'Y',
@TimeLimit=10800, 
@LogToTable = 'Y'

Хоча статистика, здавалося, була оновлена. Після запуску наступного сценарію я більше не отримував попередження про оператор сортування.

UPDATE STATISTICS [Bocss2].[dbo].[tblBOrder]  WITH FULLSCAN
--1 hour  04 min 14 sec

UPDATE STATISTICS [Bocss2].[dbo].tblBAddress  WITH FULLSCAN
-- 45 min 29 sec

UPDATE STATISTICS  [Bocss2].[dbo].tblBAccountHolder WITH FULLSCAN
-- 26 SEC

UPDATE STATISTICS  [Bocss2].[dbo].tblBAccountParticipant WITH FULLSCAN
-- 4 min

UPDATE STATISTICS  [Bocss2].[dbo].tblBAccountParticipantAddress WITH FULLSCAN
-- 7 min 3 sec

На скільки скорочено час запиту?
впливовий

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

Відповіді:


17

як щодо рівня 2? Я не зміг знайти нічого, пов’язаного з рівнем 2.

Відповідно до цього старого документа MS, число в розливі Tempdb означає, скільки проходів потрібно для даних для сортування даних. Отже, Spill 1 означає, що він повинен пройти 1 раз для сортування даних, а 2 означає, що він повинен пройти 2 рази.

Цитуючи з блогу:

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

чому 70? Я використовую сервер sql 2014

Це пояснюється тим, що рівень сумісності бази даних на зображенні НЕ 120 (що означає рівень сумісності бази даних 2014 року), оскільки це не 120 запитів буде оброблено за допомогою старої моделі оцінки кардинальності (CE), на яку посилається CardinalityEstimationModelVersion="70". Я впевнений, що вам відомо, що з SQL Server 2014 у нас є новий CE.

як я можу позбутися цього оператора сортування (якщо це взагалі можливо)?

Відмінна команда, яку ви використовуєте, викликає операцію сортування. Дані, які сортуються, не вміщуються в пам'ять, тому вони розливаються до tempdb, і коли це відбувається, своєрідне попередження із жовтим знаком оклику подається у плані виконання. Сортування попереджень не завжди є проблемою.

У плані виконання ви бачите, що передбачувана кількість рядків для сортування дорівнює 1, але 16353 зустрічаються під час виконання. Обсяг пам'яті, зарезервований для сортування, ґрунтується на очікуваному (передбачуваному) розмірі вхідного даних та не може зростати під час виконання (у цьому випадку).

Невеликий грант пам’яті для запиту (1632 КБ) також розподіляється між операторами, що споживають пам'ять, що споживають одночасно (сортування та «оптимізований» цикл приєднується). У вашому плані це означає, що 33,33% (544 КБ) доступні сорту під час читання рядків (частка вхідної пам'яті). Цього не вистачає пам’яті для сортування 16353 рядків, тому вона розливається до tempdb . Однорівневого розливу недостатньо для завершення сортування, тому потрібен другий рівень розливу (див. Посилання в кінці для отримання більш детальної інформації про рівні розливу).

Сортування властивостей

Сортуйте властивості так, як їх переглядають у SQL Plan Explorer

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

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

PLE - це показник активності вводу / виводу, збільшився він ?. Так трапляється це часто або лише тоді, коли ви виконуєте певний запит, чи це сталося саме сьогодні. Уникайте реакції ривка коліна, спочатку ми повинні переконатися, що ви справді стикаєтесь із тиском пам’яті або причиною цього є якийсь негідний запит, який генерує занадто багато вводу / виводу. У будь-якому випадку у вас вже є пам'ять 97 G, призначена для SQL Server.

Для отримання додаткової інформації про рівень розливу та проблему висхідного ключа див.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.