powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Вступление в партицирование
36 сообщений из 36, показаны все 2 страниц
Вступление в партицирование
    #39782566
Oblom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день
Пытаюсь впервые разобраться с партицированием. Задача: убедиться по плану запроса, что выбираются данные только из той партиции, в которой лежат нужные данные.

Нашел статью коллеги Гладченко тынц
где написано следующее:
если выполнить
Код: sql
1.
2.
3.
4.
5.
create partition function pf(int) as range for values (0, 10, 100)
create partition scheme ps as partition pf all to ([PRIMARY])
create table t (a int, b int) on ps(a)

select * from t where a < 0


то в плане выполнения будет
|–Table Scan(OBJECT:([t]), WHERE:([t].[a]<(0)) PARTITION ID:((1)))

Однако, когда указанное выполняю я, вижу:
|--Table Scan(OBJECT:([master].[dbo].[t]), SEEK:([PtnId1001] >= (1) AND [PtnId1001] <= RangePartitionNew(CONVERT_IMPLICIT(int,[@1],0),(0),(0),(10),(100))), WHERE:([master].[dbo].[t].[a]<CONVERT_IMPLICIT(int,[@1],0)) ORDERED FORWARD)

Что я делаю не так?
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39782573
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oblom,

У вас запрос параметризировался и вы столкнулись с так называемым dynamic partition elimination.

если добавить option (recompile) получите что хотите
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39782611
Oblom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
felix_ffOblom,
У вас запрос параметризировался и вы столкнулись с так называемым dynamic partition elimination.
если добавить option (recompile) получите что хотите
Запустил с recompile, получил:
|--Table Scan(OBJECT:([master].[dbo].[t]), SEEK:([PtnId1001]=(1)), WHERE:([master].[dbo].[t].[a]<(0)) ORDERED FORWARD)

Вроде непохоже на пример из статьи, или это одно и то же, записанное разными словами?
И как уйти от dynamic partition elimination не используя RECOMPILE? а то для промышленных решений как-то жестковато.
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39782620
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OblomИ как уйти от dynamic partition eliminationЗачем? Неэстетично выглядит?

Вам вообще для чего секционирование? Веяние моды?
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39782623
Oblom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmOblomИ как уйти от dynamic partition eliminationЗачем? Неэстетично выглядит?

Вам вообще для чего секционирование? Веяние моды?

Общая задача:
Есть DWH с несколькими таблицами фактов более 100 млн. каждая
Есть кубы на этих таблицах секционированных по годам, код партиций в кубе вида "WHERE Date >='20180101' AND Date < '20190101' "
Ежедневно пересчитываются партиции последнего года или последних двух лет.
Показалось разумным секционировать таблицы фактов синхронно кубам, чтобы ускорить ежедневный пересчет кубов за счет того, что выборка будет не по всей таблице, а по 1-2 последним партициям.

Мне теперь надо понять по плану запроса, что моё секционирование решило поставленную задачу.
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39782648
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oblomчтобы ускорить ежедневный пересчет кубовСекционирование - средство администрирования, а не ускорения. Кластерный индекс справится не хуже.
А если на ваших таблицах уже есть индексы, то секционирование еще и добавит головной боли.
OblomМне теперь надо понять по плану запроса, что моё секционирование решило поставленную задачу.Не пробовали почитать что такое "dynamic partition elimination"?
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39782651
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oblom,

у Фридмана хорошо описан сам процесс:
почитайте https://blogs.msdn.microsoft.com/craigfr/2006/11/27/introduction-to-partitioned-tables/
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39782701
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OblominvmВам вообще для чего секционирование? Веяние моды?Показалось разумным секционировать таблицы фактов синхронно кубам, чтобы ускорить ежедневный пересчет кубов за счет того, что выборка будет не по всей таблице, а по 1-2 последним партициям.Понятно, веяние моды.
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39782792
Oblom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmНе пробовали почитать что такое "dynamic partition elimination"?

Попробовал, почитал и понял. Более того, в моем случае, его таки нет, а если и будет, то не смертельно.

Хоть бы раз здесь в моей теме не написали "вам это нафиг не надо", вместо того, чтобы хотя бы кинуть ссыль на документацию, которую надо почитать. Если уж своими словами лениво объяснить, имея опыт.
Весь опыт по любой теме всегда сводится к "вам это нафиг не надо".

Спасибо всем, вопрос закрыт.
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39782835
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oblom,

кубы обновляют при помощи SSIS и change tracking, если не ошибаюсь.
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39782847
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oblom,

Типы должны быть приведены явно к типу аргумента функции секционирования:

Код: sql
1.
select * from t where a < cast(0 as int)



Если не соблюдать это правило, можете получить просмотр всех секций. В вашем случае просмотрена была только одна. Если "шашечки" важнее, чем "ехать", то проблема, наверное, есть.
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39782876
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав КолосовТипы должны быть приведены явно к типу аргумента функции секционированияСможете объяснить как же тогда работает исключение секций в вышеприведенном примере?
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39782879
Фотография StarikNavy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oblom
Хоть бы раз здесь в моей теме не написали "вам это нафиг не надо", вместо того, чтобы хотя бы кинуть ссыль на документацию, которую надо почитать. Если уж своими словами лениво объяснить, имея опыт.

именно это вам своими словами и написали:
"Секционирование - средство администрирования, а не ускорения. Кластерный индекс справится не хуже."
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39782881
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
StarikNavy,

конечно же это неправда. Секции эффективны при просмотре данных в плане запроса.
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39782882
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm,

увы, нет, я не настолько детально знаю особенности движка.
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39782906
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав КолосовСекции эффективны при просмотре данных в плане запроса.Расшифруйте.
Владислав Колосовувы, нет, я не настолько детально знаю особенности движка.Тогда на основании чего вы даете такие рекомендации?
И почему ваше предложение обязательно для предикатов со столбцом секционирования, а не вообще для всех?
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39782983
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm,

насколько я видел в планах, использование секций приводит к просмотру меньшего количества данных и, вместо просмотра всех строк таблицы, запрос читает лишь строки секции, попадающую в заданный предикатом диапазон.

Обязательно потому, что, как показывает практика, неявное преобразование может привести к просмотру всех секций вместо тех, которые подходят в заданные условия.
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39782995
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проблему легко увидеть, слегка изменив пример:

Код: sql
1.
2.
3.
4.
5.
create partition function pf(int) as range for values (0, 10, 100)
create partition scheme ps as partition pf all to ([PRIMARY])
create table t (a int, b int) on ps(a)

select * from t where a < cast(0 as bigint)
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39783003
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав Колосовнасколько я видел в планах, использование секций приводит к просмотру меньшего количества данных и, вместо просмотра всех строк таблицы, запрос читает лишь строки секции, попадающую в заданный предикатом диапазон.А соответствующий индекс будет работать как-то иначе?
Владислав КолосовОбязательно потому, что, как показывает практика, неявное преобразование может привести к просмотру всех секций вместо тех, которые подходят в заданные условия.Ну так почему же ваше правило не обязательно для поиска по индексу?
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39783077
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm,

хорошие вопросы, надо подумать. Вы имеете в виду поиск диапазона в кластерном индексе?
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39783095
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав Колосов,

как по мне плюшки исключения секций в плане сайдэффекта увеличения производительности можно сравнивать только в случае сканирования индекса.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
create partition function pf(int) as range for values (0, 10, 100)
create partition scheme ps as partition pf all to ([PRIMARY])
create table t (a int, b int) on ps(a)

insert into t (a, b)
select top (1000) 10, row_number() over (order by 1/0) from master.dbo.spt_values
insert into t (a, b)
select top (2000) 200, row_number() over (order by 1/0) from master.dbo.spt_values

create index ix on t(a) on ps(a)
create index ix2 on t(a) on [primary]
update statistics t with fullscan

select index_id, rows, partition_number, total_pages, used_pages 
from sys.partitions p
   join sys.allocation_units au on au.container_id = p.partition_id
where p.object_id = object_id('t')


set statistics io, time on
select a from t with(index(ix), forcescan) where a>100 --прочитает 2000 строк
go
select a from t with(index(ix2), forcescan) where a>100 --прочитает 3000 строк
go
set statistics io, time off
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39783103
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
felix_ff,

у меня как раз ситуация с большим количеством ad hoc запросов и достаточно широкой таблицей, по которой все наборы индексов строить не оптимально. Разделение на секции дало многократный рост производительности, поскольку запросы обращаются к относительно небольшим интервалам временнЫх меток данных. Теперь мне интересно проверить - как изменится план и производительность, если я уберу секции и оставлю тот же кластерный индекс.
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39783151
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав КолосовВы имеете в виду поиск диапазона в кластерном индексе?В любом, не требующем лукапов.

Возможность позиционирования по секции или по индексу определяется саргабельностью предиката.
В случае допустимости неявного приведения типов, саргабельность предиката зависит от приоритетов типов левой и правой части предиката.
Если тип справа приоритетнее - потребуется явное приведение.
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39783173
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
felix_ffкак по мне плюшки исключения секций в плане сайдэффекта увеличения производительности можно сравнивать только в случае сканирования индекса.Ваш пример очень искусственный. И без форсирования сканирования не работает.

Но в реальности увеличение производительности при секционировании вполне возможно. Например, когда столбец секционирования не первый в индексе.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
use tempdb;
go

create partition function pf(int) as range for values (0, 10, 50, 100);
create partition scheme ps as partition pf all to ([PRIMARY]);
create table t (a int, b int, c int, dummy char(8000) null) on ps(b);

insert into t (a, b, c)
select top (1000) 1, 0, row_number() over (order by 1/0) from master.dbo.spt_values
union all
select top (1000) 1, 10, row_number() over (order by 1/0) from master.dbo.spt_values
union all
select top (1000) 1, 50, row_number() over (order by 1/0) from master.dbo.spt_values
union all
select top (1000) 1, 100, row_number() over (order by 1/0) from master.dbo.spt_values
union all
select top (1000) 2, 0, row_number() over (order by 1/0) from master.dbo.spt_values
union all
select top (1000) 2, 10, row_number() over (order by 1/0) from master.dbo.spt_values
union all
select top (1000) 2, 50, row_number() over (order by 1/0) from master.dbo.spt_values
union all
select top (1000) 2, 100, row_number() over (order by 1/0) from master.dbo.spt_values;

create index ix on t(a, b) include (c, dummy) on ps(b)
create index ix2 on t(a, b) include (c, dummy) on [primary]
go

set statistics io, time on

declare @c int;

select @c = count(*) from t with (index = ix) where a > 0 and b in (0, 100) and c = 50;
select @c = count(*) from t with (index = ix2) where a > 0 and b in (0, 100) and c = 50;

set statistics io, time off
go

drop table t;
drop partition scheme ps;
drop partition function pf;
go
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39783191
Фотография Yasha123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав Колосовfelix_ff,

у меня как раз ситуация с большим количеством ad hoc запросов и достаточно широкой таблицей, по которой все наборы индексов строить не оптимально. Разделение на секции дало многократный рост производительности, поскольку запросы обращаются к относительно небольшим интервалам временнЫх меток данных. Теперь мне интересно проверить - как изменится план и производительность, если я уберу секции и оставлю тот же кластерный индекс.
так если вам "помогло" секционирование, то ключ секционирования присутствовал во всех where. значит, дата есть во всех этих таблицах и кластерный по дате вам обеспечил бы ровно такой же выборочный просмотр диапазона
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39783199
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Yasha123Владислав Колосовfelix_ff,

у меня как раз ситуация с большим количеством ad hoc запросов и достаточно широкой таблицей, по которой все наборы индексов строить не оптимально. Разделение на секции дало многократный рост производительности, поскольку запросы обращаются к относительно небольшим интервалам временнЫх меток данных. Теперь мне интересно проверить - как изменится план и производительность, если я уберу секции и оставлю тот же кластерный индекс.
так если вам "помогло" секционирование, то ключ секционирования присутствовал во всех where. значит, дата есть во всех этих таблицах и кластерный по дате вам обеспечил бы ровно такой же выборочный просмотр диапазонаУгу, тут нужно не "оставлю тот же кластерный индекс", а "сделаю вместо партицирования такой кластерный индекс, который обеспечсит работу в той же области диска, как и партицирование".

Как в примере invm на самом деле показано не увеличение производительности при секционировании, наоборот, показано уменьшение производительности без секционирования, в случае, когда столбец не первый в индексе:invmНо в реальности увеличение производительности при секционировании вполне возможно. Например, когда столбец секционирования не первый в индексе.
Но зачем его делать не первым?

Если таблица секционируется по дате, дата, разумеется, всегда включена в запросы (иначе секционирование не будет работать), тогда достаточно вместо секционирования просто сделвать дату первым полем в кластерном индексе, и запросы с и без секционирования будут выполняться одинаково по скорости.


А то странное сравнение - давайте сравним запрос к секции, с запросом к таблице без индексов - ооо, секционирование рулит!!!
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39783210
Гавриленко Сергей Алексеевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexeyvgЕсли таблица секционируется по дате, дата, разумеется, всегда включена в запросы (иначе секционирование не будет работать)Не должна. Секционирование работать будет, а вот partition elimination -- нет. Просто придется лазить во все партиции: при скане и так понятно, при поиске по индексу -- будет seek в каждую партицию.
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39783244
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гавриленко Сергей АлексеевичalexeyvgЕсли таблица секционируется по дате, дата, разумеется, всегда включена в запросы (иначе секционирование не будет работать)Не должна. Секционирование работать будет, а вот partition elimination -- нет. Просто придется лазить во все партиции: при скане и так понятно, при поиске по индексу -- будет seek в каждую партицию.Мы стравниваем затраты на доступ к данным в секционированной таблице, и в несекционированной. А не тонкости работы секционирования.
"секционирование не будет работать" - я имел в виду, что не будет выполняться исходная цель - с помощью секционирования уменьшить расходы на выполнение запроса.

То есть рассматриваем такую ситуацию:

В 2х таблицах есть поле [Год]

В первой таблице оно используется для разделения на секции
Во второй таблице оно включено в кластерный индекс первым полем.

В этих двух вариантах в запросах WHERE [Год] = nnn AND <другие условия> сервер будет читать данные из одной области диска, в первом случае, определённой секционированием, во втором случае диапазонм кластерного индекса.

Т.е. разницы в производительности такого запроса не будет.
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39783682
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm,

хочу парировать на тему "секционирование - средство администрирования"
т.к. сам пользуюсь именно для ускорения обсчета кубов, а не для удобства управления.
но никогда тесты не проводил, а теперь вдруг захотелось.

имеем базу и 2 аналогичные таблицы на ~300млн строк,
одна (t1) с кластерным индексом по полю типа datetime (со временем), вторая (t2) секционирована по полю типа int в формате YYYYMM (т.е. месяц года) в каждой секции примерно 11млн записей

и на том же сервере, но на другом диске куб с тремя измерениями:
dates - с 09/2016 по 03/2019, ключ типа int в формате YYYYMMDD
clients - примерно 4млн записей, ключ типа bigint
sales_orders - ключ типа инт - тупая нумерация продаж в некоем разрезе, не больше 1000 записей
и 4 группы мер у которых:
1. из t1 в группу мер sales_1_1 c одной секцией
2. из t1 в группу мер sales_1_N c ежемесячными секциями по условию (пример) sale_date between '20181201' and '20181231 23:59:59'
3. из t2 в группу мер sales_N_1 c одной секцией
4. из t2 в группу мер sales_N_N c ежемесячными секциями по условию (пример) sale_month = 201812

в каждой, 2 меры, сумма по полю sales_fact и distinct_count по полю order_number (связь с измерением sales_order) что накладывает требование по дополнительной сортировке данных.

обработка измерений сделана заранее.
обработка групп мер - full process. причем, для каждого случая предварительно рестарт SQL и SSAS, и две последовательные обработки, на графиках, каждый раз вторая.

дальше графики, единственное пояснение для них всех - гафики начинаются с момента старта процессинга. до начала получения данных (розовый толстый) это как раз и есть работа SQL по сортировке (эту оптимизацию не делал нигде, никак).
(модераторов прошу простить за широкие графики и пустые места, которые можно было бы сократить, но сделано это только для удобства сравнения)
смотрим:
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39783683
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sales_1_1
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39783684
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sales_1_N
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39783685
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sales_N_1
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39783686
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sales_N_N
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39783687
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да, забыл, в настройках процессинга 20 соединений максимум, т.е. одновременно не более 20 секций
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39783695
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Столбец секционирования действительно у меня не первый в индексе, мне он и не нужен первым. Например ID (уникальный) + DATE (секции). Я выбираю в этом случае одну строку поиском по ID или выбираю просмотр секции запросом диапазона дат или использую дополнительные фильтры. Для AdHoc запросов по нагруженной таблице это отличный вариант, т.к. избавляет меня от хранения и поддержания многочисленных индексов.

Я к тому, что утверждение "секционирование только для администрирования" не является истинным.
...
Рейтинг: 0 / 0
Вступление в партицирование
    #39783700
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гипотетически. Мне требуется ежемесячно выполнять сложный расчет для накопленных данных в одной таблице. Я создаю 20 секций, создаю сиквенс, который разбрасывает данные по секциям.
У меня 100500 ядер и я запускаю в параллель 20 расчетов, каждый из которых съедает 4-6 ядер. Вот и профит от секционирования.
Если не ошибаюсь, сейчас придумали эскалацию до секции, так что удержаний таблицы не будет.
...
Рейтинг: 0 / 0
36 сообщений из 36, показаны все 2 страниц
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Вступление в партицирование
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]