Русский
Русский
English
Статистика
Реклама

Перевод Секционирование таблиц и время компиляции плана запроса в SQL Server

Для будущих учащихся на курсе "MS SQL Server Developer" подготовили перевод полезной статьи.

Также приглашаем всех желающих на открытый вебинар на тему
Polybase: жизнь до и после. На вебинаре рассмотрим, как можно было взаимодействовать с другими базами данных до Polybase, и как это работает сейчас.


Меня иногда спрашивают: Если в таблице много индексов и SQL Server вынужден анализировать больше вариантов, то не замедлит ли это построение плана запроса?

Что же, вполне может быть, но что действительно сбивает с толку оптимизатор, так это секционирование. Даже простейшие запросы к секционированным таблицам могут привести к значительному увеличению использования процессорного времени. Хуже того, как однажды сказал знаменитый философ: Больше секционирования больше проблем.

Итак, давайте возьмем какую-нибудь из баз данных Stack Overflow и создадим функцию секционирования, которая будет разбивать наши данные по дням:

USE StackOverflow;GO/* Create date partition function by day since Stack Overflow's origin,modified from Microsoft Books Online: https://docs.microsoft.com/en-us/sql/t-sql/statements/create-partition-function-transact-sql?view=sql-server-ver15#BKMK_examples DROP PARTITION SCHEME [DatePartitionScheme];DROP PARTITION FUNCTION [DatePartitionFunction];*/DECLARE @DatePartitionFunction nvarchar(max) =     N'CREATE PARTITION FUNCTION DatePartitionFunction (datetime)     AS RANGE RIGHT FOR VALUES (';  DECLARE @i datetime = '2008-06-01';WHILE @i <= GETDATE()BEGIN  SET @DatePartitionFunction += '''' + CAST(@i as nvarchar(20)) + '''' + N', ';  SET @i = DATEADD(DAY, 1, @i);  END  SET @DatePartitionFunction += '''' + CAST(@i as nvarchar(20))+ '''' + N');';  EXEC sp_executesql @DatePartitionFunction;  GO   /* Create matching partition scheme, but put everything in Primary: */CREATE PARTITION SCHEME DatePartitionScheme  AS PARTITION DatePartitionFunction  ALL TO ( [PRIMARY] ); GO

Далее создадим секционированную копию таблицы Users, разбив ее по значениям в колонке CreationDate:

DROP TABLE IF EXISTS dbo.Users_partitioned;GOCREATE TABLE [dbo].[Users_partitioned]([Id] [int] NOT NULL,[AboutMe] [nvarchar](max) NULL,[Age] [int] NULL,[CreationDate] [datetime] NOT NULL,[DisplayName] [nvarchar](40) NOT NULL,[DownVotes] [int] NOT NULL,[EmailHash] [nvarchar](40) NULL,[LastAccessDate] [datetime] NOT NULL,[Location] [nvarchar](100) NULL,[Reputation] [int] NOT NULL,[UpVotes] [int] NOT NULL,[Views] [int] NOT NULL,[WebsiteUrl] [nvarchar](200) NULL,[AccountId] [int] NULL) ON [PRIMARY];GO CREATE CLUSTERED INDEX CreationDate_Id ON dbo.Users_partitioned (Id)ON DatePartitionScheme(CreationDate);GO INSERT INTO dbo.Users_partitioned (Id, AboutMe, Age,CreationDate, DisplayName, DownVotes, EmailHash,LastAccessDate, Location, Reputation, UpVotes,Views, WebsiteUrl, AccountId)SELECT Id, AboutMe, Age,CreationDate, DisplayName, DownVotes, EmailHash,LastAccessDate, Location, Reputation, UpVotes,Views, WebsiteUrl, AccountIdFROM dbo.Users;GOLets c

Сравним производительность с секционированием и без

Создадим некластеризованный индекс для таблиц Users и Users_partitioned. Обратите внимание, даже если при создании индекса для Users_partitioned не указать, что он секционирован, то он все равно будет секционирован по умолчанию, что весьма замечательно:

CREATE INDEX DisplayName ON dbo.Users(DisplayName);CREATE INDEX DisplayName ON dbo.Users_partitioned(DisplayName);

Теперь выполним чрезвычайно простой запрос, который возвращает одну строку:

SET STATISTICS TIME, IO ON;SELECT * FROM dbo.Users WHERE DisplayName = N'Brent Ozar';GOSELECT * FROM dbo.Users_partitioned WHERE DisplayName = N'Brent Ozar';GO

Планы запросов, на первый взгляд, выглядят одинаково, но обратите внимание, что стоимость запроса к несекционированной таблице составляет 0% от общей стоимости, а к секционированной 100%:

Это связано с тем, что предполагаемая стоимость запроса к несекционированной таблице значительно меньше 0,001, а оценка стоимости запроса к секционированной более 15. Что еще хуже, время компиляции (compile time), время выполнения (execution time) и количество логических чтений (logical reads) совершенно разные. На скриншоте ниже в верхней части показана статистика несекционированного запроса, а внизу секционированного (для удобочитаемости из вывода убрана лишняя информация):

И только на компиляцию плана к секционированной таблице ушло 27 мс процессорного времени. Я знаю, о чем вы подумали: Кого волнуют 27 мс процессорного времени? Но вспомните у нас был очень простой запрос! В реальной жизни вполне нормально, когда на составление плана уходит более 250 мс процессорного времени. Это означает, что в секунду на одном ядре процессора вы сможете скомпилировать только четыре запроса. Вот когда загрязнение кеша планов из-за непараметризированных запросов действительно портит вам жизнь.

Написать этот пост меня побудил один из моих клиентов, который решил секционировать все таблицы независимо от их размера при этом использовал везде одинаковую гранулярность секций, чтобы его динамические ETL-запросы остались простыми. К сожалению, даже запросы к простым таблицам конфигурации занимали более 250 мс процессорного времени только для компиляции плана.

Хорошо, но как насчет несекционированных индексов?

Давайте удалим секционированный индекс для таблицы Users_partitioned и создадим несекционированный. Обратите внимание, что для секционированной таблицы необходимо указать ON PRIMARY в качестве файловой группы, иначе любой некластеризованный индекс по умолчанию также будет автоматически секционирован.

CREATE INDEX DisplayName ON dbo.Users(DisplayName);CREATE INDEX DisplayName ON dbo.Users_partitioned(DisplayName) ON [PRIMARY];

И выполним запросы еще раз:

SET STATISTICS TIME, IO ON;SELECT * FROM dbo.Users WHERE DisplayName = N'Brent Ozar';GOSELECT * FROM dbo.Users_partitioned WHERE DisplayName = N'Brent Ozar';GO

Теперь оценки стоимостей одинаковые:

Но все-таки это только оценка. Единственное, что здесь совпадает это логические чтения:

Компиляция и выполнение плана запроса занимают больше времени, если какой-либо из задействованных объектов секционирован

Эти накладные расходы невелики, если сравнивать их с накладными расходами запросов к большим хранилищам данных, когда секционирование может уменьшить количество чтений. Но если сравнивать с небольшими объектами (например, rowstore-индексы размером до 100 ГБ), к которым часто обращаются с разнообразными запросами, требующими построения новых планов выполнения, то тогда накладные расходы на секционирование уже начинают суммироваться. Чем больше секционированных объектов, тем больше секций в каждом объекте, тем больше проблем.

Секционирование одна из тех возможностей, о которой я никогда не слышал: Вау, что бы я не сделал, секционирование всегда улучшает производительность! Скорее всего, об этом продолжат говорить: Я понятия не имел, что секционирование может создать проблемы и ТАМ.


Узнать подробнее о курсе "MS SQL Server Developer".

Смотреть открытый вебинар Polybase: жизнь до и после.

Источник: habr.com
К списку статей
Опубликовано: 01.03.2021 20:22:05
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании otus. онлайн-образование

Sql

Ms sql

Sql server

Polybase

Категории

Последние комментарии

  • Имя: Murshin
    13.06.2024 | 14:01
    Нейросеть-это мозг вселенной.Если к ней подключиться,то можно получить все знания,накопленные Вселенной,но этому препятствуют аннуннаки.Аннуннаки нас от неё отгородили,установив в головах барьер. Подр Подробнее..
  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru