Вход | Регистрация

  1  2
1С:Предприятие :: 1С:Предприятие 8 общая

Секционирование регистра накопления

Секционирование регистра накопления
Я
   VitShvets
 
28.05.18 - 15:04
А баловался ли кто-нибудь? Есть регистр накопления, остатки. Секционировал по «_Period» таблицу итогов, по годам. Когда пишу 1Совый запрос:

РегистрНакопления.МойРегистр.Остатки(, [Отбор по одному полю в 50 тысяч строк])
1С это превращает в:

exec sp_executesql('.....
....
FROM dbo._AccumRgT27531 T2 WITH(NOLOCK)
WHERE T2._Period = P1
.....' P1 datetime2(3).... '5999-11-01 00:00:00'

В итоге SQL, из за sp_executesql и не явного указания периодов, не понимает что надо поднимать только одну секцию с периодом '5999-11-01 00:00:00' и поднимает все секции. Хотя если в менеджмент студии переписать запрос на:

FROM dbo._AccumRgT27531 T2 WITH(NOLOCK)
WHERE T2._Period = '5999-11-01 00:00:00'
….

Всё работает! Разница в скорости колоссальная – 1 секунда против 3 минут.

Решение есть - отказаться от запросов 1С против прямых запросов, но уж больно не хочется этого делать. Есть идеи как можно повлиять на
РегистрНакопления.МойРегистр.Остатки ?
 
 
   VitShvets
 
101 - 20.06.18 - 16:55
(97) Не, иногда требуется посмотреть сильно прошлый период. Я попробую поиграться урезанием "старых периодов", что 8.3 умеет сама установкой минимального периода итогов. Профайлером посмотрю запросы-зависимости, попробую руками почистить. Но для начала надо понять скорость деградации таблицы итогов, особенно оперативных.
   VitShvets
 
102 - 20.06.18 - 17:10
(99) Так агрегаты ещё с 8.2, если не 8.1 появились. В 8.3 добавили им интеллекта по поводу "рекомендаций" и позволили управлять из предприятия.
(100) Я думал про 2 базы - архивная и оперативная. В оперативной последние 3-6 месяцев, в архивной всё остальное. Народ работает только в оперативной, длинная отчетность формируется в архивной. Не придумал как их создать быстро и как связывать между собой на предмет актуализации архивной. Так чтобы это работало быстро.
   Антон Долгов
 
103 - 20.06.18 - 17:39
(98) Что именно тебе надо ускорить?
   Genayo
 
104 - 20.06.18 - 17:43
(102) Объемы в сутки очень большие? РИБ не прокатит?
   romix
 
105 - 20.06.18 - 18:00
(0) Смотрели стандартную обработку Все действия - стандартные обработки - управление итогами - полные возможности?


Полные возможности

Режим полных возможностей позволяет получить полный доступ ко всем инструментам работы с итогами (закладка Итоги) и агрегатами (закладка Агрегаты) регистров накопления и регистров бухгалтерии.
   VitShvets
 
106 - 20.06.18 - 18:07
(103) Ну как обычно - проведение документов, всякие регламентные операции.  Самое тяжелое, типовые 1Совые запросы, на которые я не могу никак повлиять. Это виртуальные таблицы "срез последних" и "остатки".
(104) Очень приличные. На пределе. Если будет какой-то сбой, уже есть шанс не догнать. Особенно в контексте планов роста. РИБ по функционалу меня устраивает полностью. Скорее всего будет гибрид какой-то. Метаданные и лёгкие объекты метаданных ходят РИБом, тяжелые SQL.
   Антон Долгов
 
107 - 20.06.18 - 18:11
(106) И какой у тебя самый медленный запрос и какой у него план? Выложи в формате sqlplan
   romix
 
108 - 20.06.18 - 18:20
http://1sprogress.ru/anatomiya-registra-nakopleniya-vnutrennee-ustrojstvo-i-struktura-xraneniya.html

1С хранит текущие актуальные остатки (если поставить галку в настройках!) и хранит помесячно от сих до сих (две даты можно поставить в той же форме настроек (105).

Таблицы можно пересчитать.

То есть вот это надо посмотреть. Далее надо думать что там лучше по сути - регистр остатков или оборотов, закрывается ли он в 0, или там все время растет таблица остатков со временем.
   VitShvets
 
109 - 20.06.18 - 18:21
(107) В (0) написано. Не самый, но один из. План не выложу, но там смотреть нечего. Не интересный - более 50% кластеред индекс сик таблицы итогов в части оперативных итогов. Остальное впополам иннер джоин с времянкой-отбором и "агрегация" хэш матчем. Основное в плане, что кластеред индекс сик партиционирован, количество актуальных секций =14.
   romix
 
110 - 20.06.18 - 18:22
Пересчет таблицы итогов еще нужен ибо http://catalog.mista.ru/public/177171/
 
 Рекламное место пустует
   Антон Долгов
 
111 - 20.06.18 - 18:24
(109) без партиционирования запрос какой тормозит и какой у него план? что побудило заняться партиционированием? может надо с этого начинать?
   H A D G E H O G s
 
112 - 20.06.18 - 18:27
(109) Там остаточных предикатов точно нет?
   Антон Долгов
 
113 - 20.06.18 - 18:30
(112) а додумывай сам! хрен тебе а не sqlplan, "там смотреть нечего"
   H A D G E H O G s
 
114 - 20.06.18 - 18:35
Хотяяя.
Я правильно понимаю, что автор вытаскивает ВСЕ оперативные итоги, которых 50 тыс строк?
   mistеr
 
115 - 20.06.18 - 18:35
(102) Про схему архивная-оперативная и быструю актуализацию можно забыть. Пока 1С не разрешит использовать возможности скуля по быстрой обработке больших объемов данных средствами 1С. То есть многострочный DML.
   VitShvets
 
116 - 20.06.18 - 18:48
(105), (108) Эта история работает с режима совместимости 8.3.5. У меня 8.2.
(110) Это видел, подчерпнул оттуда пару идей.
(111) А разве не очевидно, что побудило? Скорость работы не устраивает. Причём основные тормоза именно в тех местах на, которые я повлиять не могу. Обычные "ВЫБРАТЬ бла-бла из ххх.Остатки". Или "ххх.СрезПоследних".
(113) Нельзя выкладывать. СБ и всё такое.
   VitShvets
 
117 - 20.06.18 - 18:55
(112) Вот сейчас не уверен, что точно понял о чём ты. Поясни плз, что ты имеешь ввиду, на что посмотреть?
(114) Не все, 50 тысяч из нескольких миллионов. Есть кластерный индекс, в нем первое поле период, второе поле, то что участвует в отборе.
   VitShvets
 
118 - 20.06.18 - 18:57
(115) Да я как-то не шибко жажду спрашивать разрешения у 1С... Но мне больше нравится CDC.
   H A D G E H O G s
 
119 - 20.06.18 - 18:58
(117) Отбой тревоги. Остаточный предикат работает только в диапазоне индекса. К твоей проблеме это не может относиться.
   H A D G E H O G s
 
120 - 20.06.18 - 18:58
Сейчас я попытаюсь воспроизвести твои идеи.
   nicxxx
 
121 - 20.06.18 - 19:00
(43) в кластерный может попадать из-за того, что много полей тянутся из таблицы.
Important: SQL Server does not use nonclustered indexes if it estimates that a large number of key or RID lookup operations will be required. (Korotkevitch D. - Pro SQL Server Internals)
   mistеr
 
122 - 20.06.18 - 19:00
(118) Не спрашивать разрешения это значит жить без поддержки и в постоянном страхе, что завтра с очередным обновлением платформы все поломается.

Есть еще вариант сделать хранилище в отдельной базе (не 1С), сделать его грамотно и юзать как внешний источник.
   H A D G E H O G s
 
123 - 20.06.18 - 19:05
Но вообще, цифры ты приводишь дикие.

Я грешу на непрогретый кэш.
Но даже после DROPCLEANBUFFERS у меня цифры минимальны.
Без всяких секционирований.
   H A D G E H O G s
 
124 - 20.06.18 - 19:10
SELECT count(*)
      
FROM [IEGAIS_MP].[dbo].[_AccumRgT687]

Результат: 8896130 за 49 секунд


SELECT *      
  FROM [IEGAIS_MP].[dbo].[_AccumRgT687]
  where [_Period]= ('59991101 00:00:00.000') and _Fld679RRef=0x810E000D3A22309E11E5EC30EF6782BC

После перезапуска ms sql сервер
Результат: 50598 строк за 0,6 секунд
HDD WD 5400, 2 Тб
Подозреваю, что жив кэш HDD
   H A D G E H O G s
 
125 - 20.06.18 - 19:11
0,6 секунд вполне укладывается в твою 1 секунду. Но без секционирования.
Что то не так у тебя с запросом от 1С.
   H A D G E H O G s
 
126 - 20.06.18 - 19:11
Сейчас сделаю запрос через 1С.
   H A D G E H O G s
 
127 - 20.06.18 - 19:21
Ну как бэ через 1С то совсем другой запрос получается, автор.
С вложенной таблицей и группировочкой разделенных итогов.
   H A D G E H O G s
 
128 - 20.06.18 - 19:38
В любом случае, после перезапуска 1С и MS SQL запрос
    Запрос=Новый Запрос;
    Старт=ТекущаяУниверсальнаяДатаВМиллисекундах();
    Запрос.Текст=
    "ВЫБРАТЬ
    |    ТоварыНаСкладахОстатки.Организация,
    |    ТоварыНаСкладахОстатки.ОбособленноеПодразделение,
    |    ТоварыНаСкладахОстатки.Склад,
    |    ТоварыНаСкладахОстатки.Номенклатура,
    |    ТоварыНаСкладахОстатки.Серия,
    |    ТоварыНаСкладахОстатки.КоличествоОстаток
    |ИЗ
    |    РегистрНакопления.ТоварыНаСкладах.Остатки(, Организация = &Организация) КАК ТоварыНаСкладахОстатки";
    Запрос.УстановитьПараметр("Организация",Объект.Организация);
    Выборка=Запрос.Выполнить().Выбрать();
    Стоп=ТекущаяУниверсальнаяДатаВМиллисекундах();
    Сообщить(Строка(Выборка.Количество())+" строк за "+Строка(Стоп-Старт)+" мсек.");

Выполняется:
42 074 строк за 3 002 мсек.
Размер таблицы 8896130 строк

В профайлере он же
exec sp_executesql N'SELECT
T1.Fld679RRef,
T1.Fld680RRef,
T1.Fld681RRef,
T1.Fld682RRef,
T1.Fld683RRef,
T1.Fld684Balance_
FROM (SELECT
T2._Fld679RRef AS Fld679RRef,
T2._Fld680RRef AS Fld680RRef,
T2._Fld681RRef AS Fld681RRef,
T2._Fld682RRef AS Fld682RRef,
T2._Fld683RRef AS Fld683RRef,
CAST(SUM(T2._Fld684) AS NUMERIC(22, 2)) AS Fld684Balance_
FROM dbo._AccumRgT687 T2
WHERE T2._Period = P1 AND ((T2._Fld679RRef = @P2)) AND (T2._Fld684 <> @P3) AND (T2._Fld684 <> @P4)
GROUP BY T2._Fld679RRef,
T2._Fld680RRef,
T2._Fld681RRef,
T2._Fld682RRef,
T2._Fld683RRef
HAVING (CAST(SUM(T2._Fld684) AS NUMERIC(22, 2))) <> 0.0) T1',N'P1 datetime2(3),@P2 varbinary(16),@P3 numeric(10),@P4 numeric(10)','5999-11-01 00:00:00',0x811F000D3A223D1B11E6056572D76893,0,0
   H A D G E H O G s
 
129 - 20.06.18 - 19:40
Проблема, скорее всего как раз в секциях. Он видит секции и начинает в них шарить, несмотря на индекс.
   vs84
 
130 - 20.06.18 - 20:15
(0) а если в отборе не 50 тыс, а 1 тыс - план аналогичный?
   VitShvets
 
131 - 20.06.18 - 20:23
(122) Это решается вьюхами. 1С спокойно себе работает с таблицами и не знает про вьюхи. Перенос данных спокойно себе работает со вьюхами и не знает про таблицы. Даже если 1С что-то поменяет в структуре хранения, актуализируем вьюхи, продолжаем работать.
(129) Сиквел хитро работает с секциями, они указаны в дереве индексов. В моём случае, т.к. он трогает все секции, я не получаю выигрыша от секционирования, "трогается" вся таблица, но по первому полю в индексе отбираются строки где Period = '5999-11-01'.
   H A D G E H O G s
 
132 - 20.06.18 - 20:28
Почему трогаются все секции?
   VitShvets
 
133 - 20.06.18 - 20:30
(130) На сколько я понял по тестам, ключевое отличие тут равенство или другое условие. Если взять пример (128), и предположить, что организация есть второе поле кластерного индекса после периода, то запрос:
РегистрНакопления.ТоварыНаСкладах.Остатки(, Организация = &Организация)

Полностью покроется кластерным индексом. Без дополнительных inner join. У меня же условие выглядит как:

РегистрНакопления.МойРегистр.Остатки(, ЗаказПокупателя В (ВЫБРАТЬ ВТ1.ЗаказПокупателя ИЗ ВТ1))

Где ВТ1 таблица в одно поле, 50 тысяч записей, только ссылки на заказы. И тут уже план другой получается. Поднимается по кластерному записи только по периоду, а потом иннер-джоинятся уже с ВТ1.
 
 
   VitShvets
 
134 - 20.06.18 - 20:32
(132) :) Я собственно ради решения этого вопроса и тему создал. Причём берешь 1Совый запрос, меняешь совсем чуть-чуть, получаешь даже не тех-же самых данных кардинально иной результат.
   H A D G E H O G s
 
135 - 20.06.18 - 21:07
(133) Вот мы и стали ближе к истине на 1 шаг.

Есть же теперь понимание того, что 
РегистрНакопления.МойРегистр.Остатки(, ЗаказПокупателя В (ВЫБРАТЬ ВТ1.ЗаказПокупателя ИЗ ВТ1))

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

?
   H A D G E H O G s
 
136 - 20.06.18 - 21:49
Хех.
Сделал секционирование, как у автора и нарвался на его проблему.
   H A D G E H O G s
 
137 - 20.06.18 - 21:49
Щас Дима разберется.
   H A D G E H O G s
 
138 - 20.06.18 - 22:02
Как только в запросе начинают использоваться параметры - секционирование не работает
   H A D G E H O G s
 
139 - 20.06.18 - 22:04
Секционирование работает:

exec sp_executesql N'SELECT
T1.Fld671RRef,
T1.Fld672RRef,
T1.Fld673RRef,
T1.Fld674RRef,
T1.Fld675RRef,
T1.Fld863_,
T1.Fld676Balance_
FROM (SELECT
T2._Fld673RRef AS Fld673RRef,
T2._Fld675RRef AS Fld675RRef,
T2._Fld671RRef AS Fld671RRef,
T2._Fld672RRef AS Fld672RRef,
T2._Fld674RRef AS Fld674RRef,
T2._Fld863 AS Fld863_,
CAST(SUM(T2._Fld676) AS NUMERIC(27, 3)) AS Fld676Balance_
FROM dbo._AccumRgT677 T2
WHERE T2._Period = ''59991101 00:00:00.000'' AND ((T2._Fld671RRef = 0x810E000D3A22309E11E5EC30EF6782BC)) AND (T2._Fld676 <> 0) AND (T2._Fld676 <> 0)
GROUP BY T2._Fld673RRef,
T2._Fld675RRef,
T2._Fld671RRef,
T2._Fld672RRef,
T2._Fld674RRef,
T2._Fld863
HAVING (CAST(SUM(T2._Fld676) AS NUMERIC(27, 3))) <> 0.0) T1',N'@P1 datetime2(3),@P2 varbinary(16),@P3 numeric(10),@P4 numeric(10)','5999-11-01 00:00:00',0x811F000D3A223D1B11E6056572D76893,0,0
   H A D G E H O G s
 
140 - 20.06.18 - 22:05
Секционирование не работает:

exec sp_executesql N'SELECT
T1.Fld671RRef,
T1.Fld672RRef,
T1.Fld673RRef,
T1.Fld674RRef,
T1.Fld675RRef,
T1.Fld863_,
T1.Fld676Balance_
FROM (SELECT
T2._Fld673RRef AS Fld673RRef,
T2._Fld675RRef AS Fld675RRef,
T2._Fld671RRef AS Fld671RRef,
T2._Fld672RRef AS Fld672RRef,
T2._Fld674RRef AS Fld674RRef,
T2._Fld863 AS Fld863_,
CAST(SUM(T2._Fld676) AS NUMERIC(27, 3)) AS Fld676Balance_
FROM dbo._AccumRgT677 T2
WHERE T2._Period = P1 AND ((T2._Fld671RRef = @P2)) AND (T2._Fld676 <> @P3) AND (T2._Fld676 <> @P4)
GROUP BY T2._Fld673RRef,
T2._Fld675RRef,
T2._Fld671RRef,
T2._Fld672RRef,
T2._Fld674RRef,
T2._Fld863
HAVING (CAST(SUM(T2._Fld676) AS NUMERIC(27, 3))) <> 0.0) T1',N'P1 datetime2(3),@P2 varbinary(16),@P3 numeric(10),@P4 numeric(10)','5999-11-01 00:00:00',0x811F000D3A223D1B11E6056572D76893,0,0
   H A D G E H O G s
 
141 - 20.06.18 - 22:07
Я бы на месте автора сходил бы на sql.ru, там бы сразу ответили, думаю.
   H A D G E H O G s
 
142 - 20.06.18 - 22:07
С примерами из 139 -140
   Genayo
 
143 - 20.06.18 - 22:12
(140)Интересно, что было бы на постгресе...
   H A D G E H O G s
 
144 - 20.06.18 - 22:13
В 139 префикс поиска ptnid1000=1
В 140 префикс поиска ptnid1000>=1 и ptnid1000<=3
   H A D G E H O G s
 
145 - 20.06.18 - 22:13
Собственно, у меня 3 секции
   H A D G E H O G s
 
146 - 20.06.18 - 22:14
   H A D G E H O G s
 
147 - 20.06.18 - 22:15
   H A D G E H O G s
 
148 - 20.06.18 - 22:22
Немного не то, у товарища в условии - функция.
   H A D G E H O G s
 
149 - 20.06.18 - 22:34
 
 Рекламное место пустует
   Антон Долгов
 
151 - 20.06.18 - 23:12
(149) т.е. ты слился?
   H A D G E H O G s
 
152 - 20.06.18 - 23:16
(151) system, ты не выеживайся, расскажи лучше нам, почему ты до этого сам не дошел.
   H A D G E H O G s
 
153 - 20.06.18 - 23:17
(151) Ну и статью почитай, про динамическую фильтрацию.
   Антон Долгов
 
154 - 20.06.18 - 23:17
Вот интересно, какой-то чувак из Волгограда чота прочитал где-то про что-то и решил это у себя попробовать. Ок, ему простительно, он из региона и всё такое. Но ты-то Ежов, ты же сертифицированный иксперд, как ты повелся на невнятное блеяние и начал потакать хотелкам нуба?
   H A D G E H O G s
 
Модератор
155 - 20.06.18 - 23:18
Давай, до свидания.
   breezee
 
158 - 21.06.18 - 03:06
(5) Ага, на ура...
Выбрать в () будет работать очень медленно.
Если нужно обрезать данные, то лучше использовать внутреннее соединение
   nicxxx
 
159 - 21.06.18 - 08:53
(158) Дело не в том, как ты напишешь код запроса, а в том, какой оптимизатор построит план. Он может построить одинаковый план для inner join и in ().
   ERWINS
 
160 - 21.06.18 - 09:51
РегистрНакопления.МойРегистр.Остатки(, ЗаказПокупателя В (ВЫБРАТЬ ВТ1.ЗаказПокупателя ИЗ ВТ1)) 

в часто приводит к скану. Лучше 
РегистрНакопления.МойРегистр.Остатки(, ЗаказПокупателя = &знаение)   если одно значение, тогда вроде он ВСЕГДА использует индекс сик

Кроме того попробуйте сделать для ВТ1 индекс по заказу, тогда возможен индекс мердж
   toypaul
 
161 - 21.06.18 - 10:00
"Недокументировано" лезешь в базу и хочешь чтобы 1С тебя поняла? Будь готов к тому что не поймет и "отказаться от запросов 1С"

"Есть идеи как можно повлиять на РегистрНакопления.МойРегистр.Остатки ?" есть. написать в 1С, чтобы они учли это в новых релизах
   toypaul
 
162 - 21.06.18 - 10:01
exec sp_executesql('.....
....
FROM dbo._AccumRgT27531 T2 WITH(NOLOCK)
WHERE T2._Period = P1
.....' P1 datetime2(3).... '5999-11-01 00:00:00'

я правильно понимаю что 1С генерит несколько таких запросов вместо одного? пуская и с sp_executesql. или запрос один и все портит sp_executesql?
   VitShvets
 
163 - 21.06.18 - 12:21
Уххх, какая ожесточенная схватка :) А Антон Долгов, это такой местный сумасшедший? Обижаться нельзя, ибо на таких обижаться непрактично?

(139), (140) Именно так. А круче всего результат получается, если во времянку-условие добавить ещё константное поле Период со значением '5999-11-01 00:00:00' и сделать inner join по заказу+периоду с таблицей итогов. На моих данных, сейчас 0.5 секунды против 12 без секций и 6-7 секунд с секцями.
   VitShvets
 
164 - 21.06.18 - 12:25
(144) схожу, правда мне кажется, что там сходу посоветуют как надо запрос переписать, чтобы секции сработали. А я это и так уже знаю. Мне бы 1С заставить каким-то хитрым способом объяснить сиквелу... Но схожу. Коли будет результат, сюда отпишусь.
   VitShvets
 
165 - 21.06.18 - 12:30
(158), (159) Inner join хорошо срабатывает когда соединяется с физической таблицей. Виртуальная таблица, это "select ... from (select ..." и join будет с внешним select... Т.е. отбора по заказам, в моём случае, не будет на уровне выборки из таблицы итогов.
   VitShvets
 
166 - 21.06.18 - 12:33
(160) Понятно, что "ЗаказПокупателя = &знаение" будет лучше, но мне то надо по списку заказов.
Я индексирую ВТ, но у меня на времянке индекс скан получается.
   H A D G E H O G s
 
167 - 21.06.18 - 12:35
(166) Ты же понимаешь, что ты делаешь фигню?
   VitShvets
 
168 - 21.06.18 - 12:36
(161) Я вот как раз и сопротивляюсь до последнего "недокументированному лазанью" в базу. Хочется минимальными затратами получить максимальный профит. Как обычно впрочем.
   VitShvets
 
169 - 21.06.18 - 12:40
(162) 1С генерирует один запрос. Всё портит "sp_executesql", а точнее то, что оптимизатор при построении плана не учитывает значение параметров. Не уверен что это именно оно, но очень похоже на "Parameter sniffing".
   VitShvets
 
170 - 21.06.18 - 12:41
(167) Ты про индексирование? Я не увидел разницу с индексами и без. По крайней мере по запросам, что рождает 1С. Это тесты всё.
   VitShvets
 
171 - 21.06.18 - 12:43
(167) Есть кстати жгучее желание испить немного пенных напитков и обсудить ряд жизненноважных проблем :)
   Genayo
 
172 - 21.06.18 - 13:03
(170) На 50000 записей и не увидишь...
   H A D G E H O G s
 
173 - 21.06.18 - 13:05
(170) Именно.
Если ВТ велика (больше 1000 строк, конкретное значение уж не помню) - SQL не использует индекс при соединении.
Ведь, чтобы использовать индекс - нужен nested loops - проход по строкам временной таблицы и для каждой строки временной таблицы - индексный поиск в виртуальной.
Если строк ВТ будет много - SQL может посчитать, что проще обойти обе таблицы через mergejoin.
   H A D G E H O G s
 
174 - 21.06.18 - 13:07
mergejoin будет еще более вероятен, если ВТ и Виртуальная таблицы индекскированы. Но не из-за индекса, а из-за того, что таблицы УПОРЯДОЧЕНЫ по полю поиска из за наличия этого индекса.

Но, упорядочить ВТ можно, не создавая Индекс, а отсортировав, что более дешево. Индекс опять не нужен, НО.
   H A D G E H O G s
 
175 - 21.06.18 - 13:07
В вашем примере mergejoin использован не будет
   H A D G E H O G s
 
176 - 21.06.18 - 13:10
Ибо, чтобы использовать mergejoin, нужно 2 таблицы, которых у вас пока нет, пока не выполниться поиск по Периоду из таблицы остатков.

По идее, если задать хинт на использование mergejoin, то SQL выполнит TableSpool (сохранение промежуточной таблицы в tempDB, фактически, та же временная таблица, средствами SQL) для результата отбора по периоду для таблицы остатков, дико медленную и потом сделает mergejoin с вашей временной.
   H A D G E H O G s
 
177 - 21.06.18 - 13:10
Поэтому, SQL сделает HashJoin
   H A D G E H O G s
 
178 - 21.06.18 - 13:12
SQL построит хэштаблицу для вашей временной таблицы, затем выберет записи из таблицы остатков по периоду и обойдет эти записи, ища их строки в хэштаблице.
   los_hooliganos
 
179 - 21.06.18 - 13:15
(169) Все верно. Построитель запроса не знает параметров, поэтому строит план запроса на все секции.
   los_hooliganos
 
180 - 21.06.18 - 13:20
Я бы сделал вьюху с таким вот условием:

WHERE case T2._Period = '2001-01-01 00:00:00' and '2002-01-01 00:00:00' and $PARTITION.partition_function(_Period) = 2001 then true

Секционирование заработает и особо извращаться не надо и построитель запроса все должен учесть.
   los_hooliganos
 
181 - 21.06.18 - 13:21
(180) ну ес-но в CASE сам пропиши соотношения периодов и секций
   los_hooliganos
 
182 - 21.06.18 - 13:23
точнее :)

WHERE case when view.Period between '2001-01-01 00:00:00' and '2002-01-01 00:00:00' and $PARTITION.partition_function(Period) = 2001 then true
when ... then

end
   VitShvets
 
183 - 21.06.18 - 13:30
(177), (178) У меня mergejoin получается во всех вариантах.
   H A D G E H O G s
 
184 - 21.06.18 - 13:48
(183) значит я что-то не учел.
   Fragster
 
185 - 21.06.18 - 14:27
получается автору надо поместить остатки в ВТ, а потом её уже отбирать.
   H A D G E H O G s
 
186 - 21.06.18 - 14:50
(183) Воспроизвел твою ситуацию - HashMatch
   H A D G E H O G s
 
187 - 21.06.18 - 14:54
Однако я ошибся с 1000 строк ВТ.

У меня ВТ была на 30Кстрок (при 8млн. строк таблицы остатков) - был nested_loops. 30 тыс поисков по индексу в таблице остатков.
Увеличил ВТ до 80Кстрок - стал hash_join.
Видимо, есть какое то отношение размера внешней и внутренней таблицы.
   VitShvets
 
188 - 21.06.18 - 16:54
(185) Выигрыша не будет. Это тоже самое, что получить все оперативные остатки.
   VitShvets
 
189 - 21.06.18 - 16:55
(186) У меня есть TRC, где в одном случае нестед лупс есть, но взял сейчас тот запрос, не получатся повторить, везде mergejoin...
   VitShvets
 
190 - 21.06.18 - 16:56
(187) Вот тоже такое ощущение. Сейчас записей меньше стало, планы поменялись.
   Fragster
 
192 - 21.06.18 - 17:07
(188) ну так веь ты говоришь, что у тебя все секции дергаются. а это не только оперативные остатки, но и помесячные итоги, которых в несколько (десятков) раз больше
   VitShvets
 
193 - 21.06.18 - 17:13
(191) Ты зря перестал принимать такие кругленькие штучки, что тётя доктор прописала. Береги себя.
   VitShvets
 
194 - 21.06.18 - 17:21
(192) Дёргаются, да, но по дереву индексов всёравно я получаю оперативные итоги, что на следующем шаге иннер джоянятся mergejoin-ом с времянкой-фильтром. Как итог, с сервера вытягиваются данные только по 50 тысячам заказов. Если делать внутреннее соединение с виртуальной таблицей или складывать остатки во времянку, а потом соединять две времянки, будет как минимум дольше на вытягивание всех итогов и/или создание временной таблицы.
   МихаилМ
 
195 - 25.06.18 - 23:26
  1  2

Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Рекламное место пустует