|
Секционирование регистра накопления | ☑ | ||
---|---|---|---|---|
0
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С против прямых запросов, но уж больно не хочется этого делать. Есть идеи как можно повлиять на РегистрНакопления.МойРегистр.Остатки ? |
|||
1
vde69
28.05.18
✎
15:15
|
правильно спроектировать регистр....
я не понимаю как можно угробить регистр всего в 50тыс строк что-бы он запрос делал 3 минуты.... |
|||
2
impulse9
28.05.18
✎
15:19
|
(0) индекс по полю есть? 3 минуты что-то многовато для 50 тысяч строк
|
|||
3
Вафель
28.05.18
✎
15:32
|
(1) 50 тыщ строк в отборе. а не в таблице
|
|||
4
Wingless
28.05.18
✎
15:40
|
(0) Разделители данных используются?
|
|||
5
vde69
28.05.18
✎
16:05
|
(3) для этого делается ВТ и условие ... В(выбрать Т.* из ВТ1 как Т).
работает на ура... |
|||
6
VitShvets
28.05.18
✎
16:10
|
(1), (2) В регистре сотни миллионов записей. Конкретно в таблице итогов около 300 миллионов. ОТБОР по 50 тысячам.
(2) Индекс по полю есть. Запрос попадает в кластерный индекс(сиик). (4) не используются разделители. (5) Именно так. Формируется выборка во времянку, индексируется. В отборе виртуальной таблицы указывается "ПолеОтбора В (Выбрать Ссыла ИЗ ВТ)". |
|||
7
H A D G E H O G s
28.05.18
✎
16:16
|
300 млн. в итогах - это конечно, эпик, даже если дело ведётся с бородатых лет, но я все равно не понял, что хотел сказать автор
|
|||
8
Bober
28.05.18
✎
16:16
|
(0) Герман Кудяков делал продукт на движке 1с, в котором был механизм секционирования СУБД MS SQL.
PS Нужно помнить, что при реструктуризации регистра все придется делать заново. |
|||
9
H A D G E H O G s
28.05.18
✎
16:16
|
Вангую итоги от рождества Христова
|
|||
10
ptiz
28.05.18
✎
16:17
|
(6) "Конкретно в таблице итогов около 300 миллионов" - жуть какая. Это только в таблице оперативных итогов _AccumRgT27531 ???
Из интереса: сколько последних месяцев хранится? Там примерно по столько же? |
|||
11
H A D G E H O G s
28.05.18
✎
16:19
|
Чем отличается запрос 1с от запроса автора?
|
|||
12
Bober
28.05.18
✎
16:20
|
(6) так может в таблице итогов много нулевых итогов?
В 8.3 можно управлять период рассчитанных итогов, например с 1.1.2010 по 30.04.2018 (до 8.3 нельзя было управлять датой начала расчета итогов) |
|||
13
vde69
28.05.18
✎
16:27
|
(6) а кто будет указывать первый параметр виртуальной таблицы?
РегистрНакопления.МойРегистр.Остатки(???, [Отбор]) |
|||
14
VitShvets
28.05.18
✎
16:28
|
(7) В курсе что такое секционирование и как это работает?
(8) Спасибо за наводку, пояндексю. (9) Всего лишь с 2010 года. (10) AccumRgT27531 это таблица всех итогов, за все года и месяцы. Оперативные итоги, это итоги у которых _Period = '5999-11-01 00:00:00'. (11) Это один и тот-же кусок запроса, пойманный профайлером. Разница в том, что типовой 1Совый запрос получает условие по дате как параметр, а я устанавливаю условие как константу. |
|||
15
Timon1405
28.05.18
✎
16:29
|
(13) имеются ввиду текущие остатки, для них период указывать не нужно
|
|||
16
Bober
28.05.18
✎
16:30
|
(14) какая версия СУБД и 1с?
|
|||
17
VitShvets
28.05.18
✎
16:33
|
(12) скорее много не нулевых итогов. С этим боремся, но тут помощь не нужна, вопрос не в этом.
(12) >> В 8.3 можно управлять период рассчитанных итогов, например с 1.1.2010 по 30.04.2018 Гм... А можно поподробнее? Где почитать? Я бы с удовольствием удалил итоги за 2010-2016 годы. (13) Хочется оперативных, текущих остатков. Отбор по периоду опущен специально. (15) Именно! (16) SQL Server 2012 SP4. 1С, древняя ещё толстоформенная КА на 8.3.10.2561 релизе. |
|||
18
vde69
28.05.18
✎
16:34
|
(15) кто сказал, что не нужно?
кстати интересный вопрос, что будет быстрее работать с датой или без нее.... ихмается мне что дело тут в секционности индекса, то есть в джойне нужно использовать поля соответсвующие основному индексу (при чем в правильном порядке), возможно во ВТ следует добавить несколько полей и подумать над соединением с физ таблицей... |
|||
19
vde69
28.05.18
✎
16:36
|
(17) >>>Хочется оперативных, текущих остатков. Отбор по периоду опущен специально.
попробуй период поставить такой (граница(конецмесяца(текущаядата())),истина) |
|||
20
Вафель
28.05.18
✎
16:37
|
(19) ты действительно не понимаешь какой запрос на сервер уходит и почему?
|
|||
21
Bober
28.05.18
✎
16:39
|
(17) РегистрНакопленияМенеджер.УстановитьМинимальныйИМаксимальныйПериодыРассчитанныхИтогов
и еще пара методов для работы с этой возможностью. |
|||
22
VitShvets
28.05.18
✎
16:41
|
(18) Я говорю. Если не указывать, либо в параметр периода передать пустую дату, 1С интерпретирует это как запрос к оперативным итогам. Т.е. запрос будет ТОЛЬКО к таблице итогов и ТОЛЬКО к данным где _Period = '5999-11-01 00:00:00'. В случае указания любого периода, если не будет посчитанных данных на конец месяца, 1С будет строить запрос и к итогам и к движениям. Т.е. лучше не будет точно.
|
|||
23
Локи-13
28.05.18
✎
16:41
|
(17) может проблема в версии скуля?
Почему отличается поведение по сути одинаковых запросов? |
|||
24
Bober
28.05.18
✎
16:42
|
(0) те при запросе к остаткам регистра ты получаешь идентичный запрос как если -бы ты сам его делал через студию. Запросы отличаются только в отборе по периоду.
|
|||
25
Локи-13
28.05.18
✎
16:43
|
Опять же, если
"Разница в скорости колоссальная – 1 секунда против 3 минут. " То не вижу ничего предосудительного в использовании прямого запроса |
|||
26
vde69
28.05.18
✎
16:47
|
(25) а я вижу, как ты думаешь, тому кто придет на смену с этим всем разбираться?
|
|||
27
Локи-13
28.05.18
✎
16:48
|
(26) судя по размеру базы абы кто туда не придет
|
|||
28
VitShvets
28.05.18
✎
16:51
|
(21) Гляну, спасибо.
(23) Как я понял по комментариям чистых сиквельщиков, дело в неопрееленности периода. Т.к. запрос не прямой, а через sp_executesql, отимизатор компилит его на "максимальное покрытие" (24) Не совсем. Я ловлю запрос, копирую его в менеджмент студию, выполняю, вижу что в плане поднято 14 секций вместо одной. Чуть-чуть модифицирую - указываю дату константой а не параметром, получается тот-же запрос, но поднимающий 1 секцию и работающий на порядки быстрее. (25) Я всё больше склоняюсь к этому. (26) Меньше всего меня заботит на тему, что кто-то там придёт. Во первых я сам пока никуда не собираюсь. Во вторых мне зарплату платят за то, чтобы система работала. И работала в устраивающих меня и бизнес границах. |
|||
29
VitShvets
28.05.18
✎
17:24
|
(21) + (28) Беда-печаль. Семейство методов РегистрНакопленияМенеджер.УстановитьМинимальныйИМаксимальныйПериодыРассчитанныхИтогов работают с 8.3.2, а у меня стоит режим совместимости 8.2.16. А если просто удалить записи итогов, где период меньше, например, 01.01.2017?
И кстати об удалениях, кто-нибудь пробовал чистить периодический регистр сведений методом удаления записей SQL-ем? Вот таким способом: delete from ТаблицаРегистраСведений where _Period < '2017-01-01' Натыкались на какие-то последствия? |
|||
30
ERWINS
28.05.18
✎
17:25
|
А пробывал без регистра остатков?
Иногда на больших выходит быстрее |
|||
31
VitShvets
28.05.18
✎
17:37
|
(30) в непериодический регистр сведений писать и через group by итоги считать? Или как?
|
|||
32
ERWINS
28.05.18
✎
17:41
|
(31) да
|
|||
33
ERWINS
28.05.18
✎
17:42
|
Запрос проще и оптимизатору сложнее ошибиться
|
|||
34
VitShvets
28.05.18
✎
17:46
|
В таблице движений х2 количество записей от итогов. Шансов попасть в индекс столько же, как и в секцию по итогам. Тогда уж на прямые запросы переходить, проблем имхо, будет меньше.
|
|||
35
pavig
28.05.18
✎
18:15
|
(30)
Сурово |
|||
36
ERWINS
28.05.18
✎
18:20
|
(34) а нафиг тебе индекс то?
он по большому счету не используется если есть конструкт "В" Там почти всегда используется фулскан. |
|||
37
ERWINS
28.05.18
✎
18:23
|
Остатки хороши для бухрегистров и то только потому, что они сделаны говенно.
|
|||
38
kittystark
28.05.18
✎
18:42
|
(0) пробовал изменить запрос на ЛЕВОЕ соединение с "отборными" полями с последующим ГДЕ ЕСТЬ NULL ?
|
|||
39
ERWINS
28.05.18
✎
18:54
|
(38) зачем?
основной запрос вообще не должен ничего включать кроме примитивного фильтра и группировки |
|||
40
Bober
28.05.18
✎
18:55
|
(29) тогда лучше всего посмотреть как работает секционирование на новой чистой базе 1с на SQL 2014\2016.
Где база 1с без режима совместимости и база СУБД тоже без режима совместимости. |
|||
41
Bober
28.05.18
✎
18:57
|
(29) прямым запросом все чистится без проблем. нужно только помнить что в 8.3 у такого регистра появились таблица итогов (текущий срез данных). и в таблице изменений может быть много чего зарегистрировано (но не так критично, как итоги).
|
|||
42
Genayo
28.05.18
✎
19:14
|
Были примерно такие же проблемы с оборотным регистром, перешли на использование агрегатов, и все стало хорошо. А так, оставь только актуальные итоги, и посмотри на быстродействие.
|
|||
43
VitShvets
28.05.18
✎
19:20
|
(36) В индекс оно таки попадает, в кластерный, причём сиком, а не сканом. И лопатит не всю таблицу итогов, а треть от неё. В полной таблице ещё вопрос какой индекс должен быть и как угадать попадание в него оптимизатором. Табле скан будет люто печальным, гораздо тяжелее.
(38) Пробовал join добавлять, разный, не помогает. Соединение отрабатывает после тяжелой выборки. (40) Видимо не секционирование, а установку минимального периода итогов? Посмотрю профайлером чем он там занимается, была такая идея. (41) Регистр сведений, что хочу почистить не периодический и флагов "Разрешить итоги: ххх" не стоит. Т.е. Таблиц итогов там нет. И изменения не фиксируются, данный регистр не участвует в планах обмена. Ну по крайней мере таблица регистраций изменений пуста. |
|||
44
VitShvets
28.05.18
✎
19:26
|
(42) Были бы у остаточных регистров агрегаты... Только актуальные итоги оставить не получится, иногда требуется остатки на какой-то период. Собственно секционированием я и пытался добиться использования только оперативных итогов, сложил их аккуратно в отдельную секцию... Но эта зараза не желает выбирать маленькую порцию данных, упорно читает всю таблицу. В это и вопрос, как обязать сиквел и/или 1С использовать одну секцию и не лезть куда не просят.
|
|||
45
ERWINS
28.05.18
✎
20:08
|
(43) вообще то вначале будет сканировать индекс(есть некоторая не здоровая уверенность что не кластерный), а потом выбирать цифорки уже из полной таблицы, что в принципе может быть намного дольше - 2 последовательных выборок вместо одной но большей?
"Табле скан будет люто печальным, гораздо тяжелее. " попробуй несколько запросов чуть разных подряд. Скорость удивит. |
|||
46
ERWINS
28.05.18
✎
20:09
|
(44) только если нет строк неограниченной длинны. Иначе печалька.
|
|||
47
VitShvets
28.05.18
✎
20:36
|
(45) Можно попробовать выборку из основной таблицы, без использования виртуальной "Остатки", в принципе должно тоже самое получиться. Я правильно понимаю идею? Делаю выборку по отбору с получением ресурсов и группировкой. При этом будет скорее всего индекс сик по отбору, кей-лукап для получения ресурса. Далее скорее всего будет Hash Match (Aggregate) для получения SUM. И это должно отработать быстрее получения итогов?
|
|||
48
VitShvets
28.05.18
✎
20:38
|
(46) такую ересь первым делом из регистров убрал. Было в одном месте, пока поменял ntext на nvarchar(100), попозже удалю совсем.
|
|||
49
ERWINS
28.05.18
✎
20:47
|
(47) да. быстрее, но после прогревки кеша. Т.е. если запрос выполняется часто. Проблема именно в том, что сложный запрос к остаткам иногда выбирает неверный план.
|
|||
50
ERWINS
28.05.18
✎
20:49
|
кроме того запрос прямой. думаю что там даже не будет индекссик, просто табле скан, но это быстрее, чем сложный запрос у меня вышло.
Конечно условие что все отборы должны быть максимально простыми (= или В конкретных значений) |
|||
51
VitShvets
28.05.18
✎
20:56
|
(49), (50) С горячим кэшем беда. У меня не один такой регистр, есть ещё более тяжелые, бухгалтерские. Кэш хитс болтается между 99% и 99.9% в среднем, но периодически выпадает сильно ниже. Но попробую, завтра уже, отпишусь.
|
|||
52
ERWINS
29.05.18
✎
09:39
|
(51) бухгалтерские отдельная песня. Там Субконто и соотвествено у меня этот финт не работал.
|
|||
53
МихаилМ
29.05.18
✎
09:40
|
(0) нормально будет работать . статистика не построилась.
|
|||
54
МихаилМ
29.05.18
✎
09:44
|
(8) есть защита от неправильного пересоздания - ddl триггеры. http://catalog.mista.ru/public/114634/
|
|||
55
МихаилМ
29.05.18
✎
09:45
|
(51) 80% попадание в кэш считается достаточным результатом.
|
|||
56
ERWINS
29.05.18
✎
10:02
|
(55) если эмуляция инмемори, то нормальным 100%
|
|||
57
VitShvets
29.05.18
✎
16:40
|
(8) Пояндексил я наработки Германа Кудякова. Есть у него проект, Ei, брошен лет 5 назад, по крайней мере последнее обновление датируется 6 ноября 2013 г. Но такое ощущение, что проект его связан именно с инструментом-генератором SQL запросов. Дабы не в менеджмент студии запросы писать, а в 1С мышкой тыкать.
(52) Попробовал... Что хочу сказать, 1С странная... :) Результаты действительно интересные. На inner join/where отборе с временной таблицей-отбором срабатывает индекс сиик не кластерный, всё отбирается, далее по небольшой выборке проходит кей лукап и соббственно всё. При примерно одинаковом количестве ридсов, нагрузка на ЦПУ в 100 раз меньше, время выполнения в 100 раз быстрее. Буду проверять одинаковость выборок, но... Интересно. (53) У меня каждую ночь статистика обновляется, не работает почему-то. Нужен какой-то волшебный пендель 1С и/или SQL. Вот какой? (54) Объекты что сжаты и секционированы меняются крайне редко, руками можно восстановить. Ну в моём случае. (55), (56) Я у себя заметил, т.к. база большая, если попадание в кэш опускается хотя-бы до 90%, производительность системы сильно падает. Визуально заметно на некоторых операциях. |
|||
58
МихаилМ
29.05.18
✎
17:12
|
||||
59
ERWINS
29.05.18
✎
17:56
|
(57) будут тесты, выложите плз
|
|||
60
ERWINS
29.05.18
✎
18:03
|
(57) в 2012 скл был прикол - операция где в (2 значения) вызывала индекс скан
а одно значение индекс сик поэтому приходилось делать запрос с объединением кусков |
|||
61
VitShvets
29.05.18
✎
19:56
|
(58) Ооочень похоже на parameter sniffing. Только как его победить... Для хранимок рекомендуют использовать локальные переменные. Для самописных sp_executesql рекомендуют OPTION(RECOMPILE). Но для этого надо иметь доступ к "поправить запрос", формируемый сервером 1С, чего не получается...
(59) За выкладывание могут "пожурить" некоторые службы. Но чем смогу, тем поделюсь. Взял за основу запрос 1С, убрал sp_executesql, сформировал "Отбор" как ещё одну времянку, получил примерно в 150-200 раз меньшие затраты по CPU, reads dполовину меньше, время - чуть меньше секунды. против 171(1С .Остатки) и 5-7 секунд 1С перебор физики. |
|||
62
VitShvets
29.05.18
✎
20:00
|
Есть ещё одна забавная идея, набрел на нее у Германа Кудякова http://main.1c-ei.ru/Articles/TypeQurey/
Но у меня не пока получилось влезть в чужую временную таблицу. Но правда не сильно искал, завтра продолжу. |
|||
63
ERWINS
29.05.18
✎
20:15
|
(61) все равно спасибо, за что удастся
(61) реальную временную таблицу или материализованную? (61) идея править запросы 1с? как там после этого с проблемами грязного чтения? |
|||
64
МихаилМ
29.05.18
✎
20:27
|
(62) в чужую вт можно было влезть на ms sql 2000
в 2005 фичу закрыли |
|||
65
МихаилМ
29.05.18
✎
20:42
|
(0) у меня ощущение, что поигрались с флагами трассировки
не должно так работать. |
|||
66
МихаилМ
29.05.18
✎
20:50
|
(0) про отимизирующие флаги трассировки и секционирование
http://www.queryprocessor.ru/enable_query_optimizer_hotfixes/ какая у вас версия скл и уровень совместимости ? |
|||
67
VitShvets
30.05.18
✎
19:24
|
(63) реальную временную. Но Михаил в (64) прав, такой финт ушами не пройдёт на сиквелах 2005 и старше. По крайней мере я не нашел как это сделать, а "старшие товарищи", они-же чистые сиквельщики (и DBA и прогеры), крутят пальцем у виска.
(63) Править именно запросы 1С не получится. Была идея "подменить" часть алгоритма, как описано у Германа, ссылка в (62). Выполняем часть запроса, подменяем одну из временных таблиц своим содержимым, идём дальше по алгоритму. С грязным чтением всё также как и у 1С. В обработках-отчётах везде поголовно (nolock). Теоретически можно на снапшот поменять, но об этом думать буду если всётаки 100% решу переходить на прямые запросы. (65), (66) Не игрались флагами, но сегодня попробую: 1. Как рекомендует 1С в https://its.1c.ru/db/metod8dev#content:5904:hdoc включить флаг трассировки 4199. 2. Включу режим совместимости 110, была 100. Связался на инфостарте с Германом, он ответил. Не ожидал если честно :) Он посоветовал сменить версию SQL. Завтра займусь, на тестовой среде попробую поднять 2016 SQL и поиграться с текущей и последней платформой 1С. Посмотрю что там получится. Про сервер я писал в (17), у меня SQL Server 2012 SP4. Попробовал, кстати рецепт по лечению parameter sniffing - OPTION(RECOMPILE). Руками, в менеджмент студии, подсовывая свою времянку. План запроса не поменялся, но быстрее отработал блок Inner Join - стоимость оператора снизилась на 30%. В целом по запросу, ридсы остались те-же, но CPU и время выполнения снизились на 30%. Но это так, больше академическая история, цель выйти на одну секцию. |
|||
68
МихаилМ
30.05.18
✎
23:08
|
кстати можно попробовать заменить таблицу представлением
и в представлении указать план запроса. |
|||
69
VitShvets
31.05.18
✎
13:50
|
Включение флаги трассировки и совместимость не сильно, но помогли. Результат сопоставим с OPTION(RECOMPILE) (67), но задачу секций не решили. Буду тест разворачивать, но это вопрос не одного дня.
(68) Оригинально... Попробую как-нибудь. |
|||
70
los_hooliganos
01.06.18
✎
11:17
|
(69) В SQL есть условие на секцию в которую пойдет запрос. Если надо брать только 1 секцию, значит на нее и надо ставить условие.
Но судя по (0) проблема в незнании оптимизатора запроса о переменной которую получит итоговый запрос, поэтому план запроса и строится по всем секциям. Я бы изменил хранимку, которая ставила в запрос секцию или условие на период константой (прямо прописанной в запросе). |
|||
71
H A D G E H O G s
01.06.18
✎
11:40
|
Ткните меня в "где почитать про секции"
|
|||
72
Мандалай
01.06.18
✎
11:57
|
msdn.com
|
|||
73
Salimbek
01.06.18
✎
12:00
|
РегистрНакопления.МойРегистр.Остатки(, [Отбор по одному полю в 50 тысяч строк])
--- А если попробовать слегка наоборот --- (Выбрать * ИЗ РегистрНакопления.МойРегистр.Остатки(,)) Соединение [Отбор по одному полю в 50 тысяч строк] --- Смысл такой, что первым запросом поднимается только одна секция, а далее соединением на нее накладываем поиск... |
|||
74
VitShvets
01.06.18
✎
13:11
|
(70) >> Я бы изменил хранимку, которая ставила в запрос секцию.
Я в 1С пишу Выбрать [Поля] ИЗ РегистрНакопления.МойРегистр.Остатки(, [Отбор по одному полю в 50 тысяч строк]) Что где поправить, о какой хранимке речь? [Отбор по одному полю в 50 тысяч строк] это условие вида: Измерение В (Выбрать ВТ.Ссылка ИЗ ВТ) (70) Я пробовал в запрос константы простых типов запихивать - дату, строку. 1С упорно добавляет это в параметры. |
|||
75
VitShvets
01.06.18
✎
13:15
|
(71) Вот неплохая статейка http://www.sql.ru/articles/mssql/2005/073102partitionedtablesandindexes.shtml
|
|||
76
VitShvets
01.06.18
✎
13:22
|
(73) Не получается. Была мысль, проверял, добавить во времянку-отбор константой дату и соединять по Ссылке и дате. Проблема в том, что запрос, порождаемый 1С выглядит так:
select [поля] from ( select [измерения] SUM([ресурсы]) from [таблица итогов] where _Period = @1 AND [Остальные условия виртуальной таблицы] group by [измерения] having by SUM([ресурсы]) <> 0 ) |
|||
77
тарам пам пам
01.06.18
✎
13:23
|
(0) А если запихать пустую дату в текст 1с запроса в виде ДАТАВРЕМЯ(0,0,0,0,0,0)?
|
|||
78
VitShvets
01.06.18
✎
13:24
|
+ к (76). Так вот условия любого join накладываются на внешний запрос. Внутренний как поднимал 14 секций, так и поднимает...
|
|||
79
VitShvets
01.06.18
✎
13:30
|
(77) Пустая дата в 1С, это таки ДАТАВРЕМЯ(1, 1, 1). Но в запрос это также приходит параметром:
exec sp_executesql N'SELECT ... @10 ...@P4 datetime2(3)... '2001-01-01 00:00:00' |
|||
80
los_hooliganos
01.06.18
✎
13:42
|
(79) Попробуй таблицу подменить вьюшкой.
А в запросе вьюшки сделай условие, что берется только секция текущего года. https://docs.microsoft.com/ru-ru/sql/t-sql/functions/partition-transact-sql?view=sql-server-2017 В. Получение всех строк из одной секции секционированной таблицы или индекса Следующий пример иллюстрирует получение всех строк, которые содержит секция 5 таблицы TransactionHistory SELECT * FROM Production.TransactionHistory WHERE $PARTITION.TransactionRangePF1(TransactionDate) = 5 ; Yj ns ukfdyjt gjcnfdm 'nj yf dm.ire |
|||
81
los_hooliganos
01.06.18
✎
13:43
|
(80) Поставь условие секции на вьюшку.
Раз вьюшка будет брать только актуальную секцию, то и проблем со сканированием всех секций не будет |
|||
82
VitShvets
01.06.18
✎
15:30
|
(80), (81) Предлагаешь сделать материализованную вьюху? А как 1С отнесется с записи в это безобразие? Ну и остаются всё-таки куча запросов, где период указывается и период приходит не 5999-11-01, а скажем 4018-05-01...
|
|||
83
los_hooliganos
01.06.18
✎
15:48
|
(82) тут по разному можно извратится.
можно измерение Секция с вьюхой сделать. можно сделать копию РН, а потом в скуле реал таблицу подменить вьюхой секции. Если надо, сделать столько копий РН сколько нужно |
|||
84
los_hooliganos
01.06.18
✎
15:48
|
(83) +столько копий, сколько секций
|
|||
85
VitShvets
01.06.18
✎
15:58
|
(83) Тогда уж проще на прямые запросы перейти. По крайней мере в отчетах-обработках, где не нужна блокировка. Пока покручу идею в голове, хочу таки протестировать что покажет sql 2016 + последний релиз 1С.
(84) Регистр 100 гигов весит. Две таблицы с индексами и прочим. :) |
|||
86
kauksi
01.06.18
✎
16:13
|
Версия 8.3.10 у вас не самая удачная. Хотя может дело и не в ней
|
|||
87
VitShvets
01.06.18
✎
20:31
|
(86) Скорее всего дело вообще не в 1С. Я немного надеюсь на переработанный оптимизатор 2016-го сиквела и его хот-фиксы. Замена релиза 1С я думаю вообще ничего не поменяет. Если только режим совместимости не перевести в "Не использовать" и реструктуризировать всю базу. Но, боюсь я себе не смогу такого позволить, хотя скорее всего попробую на тестовой площадке.
|
|||
88
los_hooliganos
05.06.18
✎
11:07
|
(87) Может достаточно будет выделить таблицы регистра в отдельный файл и хранить на отдельном диске для повышения производительности? :)
|
|||
89
VitShvets
19.06.18
✎
21:08
|
(88) По оборудованию и разнесению файлов всё хорошо...
Оставлю тут, вдруг будет кому интересно-полезно. Попробовал я на тестовой площадке и разные релизы 1С и сиквел 2016 с разными настройками совместимости и параметрами запуска сиквела. Не помогает, упорно оптимизатор поднимает все секции. Мой вывод - только прямые запросы. Пока правда не решил через что - АДО понятно, думал попробовать внешние источники данных, может там есть какие-то "полезные плюшки", но руки пока не дошли. Пересчитал я итоги. По очереди, по кусочкам... Не ожидал я конечно ТАКОГО результата. Оказывается 1С ооочень сильно любит оставлять пустые и "несхлопутые" записи, особенно если включено "разделение итогов". Пересчет итогов снизил количество записей в таблице итогов более чем в 2 раза. Плюс повесил индексов несколько мимо 1С. Плюс переписал немного запросы под эти индексы. Как результат, скорость выполнения ряда тяжелых операций снизилась на 30-40%. Буду ещё бизнес-логику менять, хочу уйти от некоторых тяжелых операций. Плюс прямые запросы. Но это пробовать-экспериментировать. На "послеотпускную пору", на осень. |
|||
90
Fragster
гуру
19.06.18
✎
23:41
|
Сделать свои итоги, с блекджеком и регистрами сведений уже предлагали? А этот регистр превратить в оборотный... Кстати, кто-нибудь тестировал агрегаты на настоящих задачах? или это технологическое упражнение без реального применения?
|
|||
91
mistеr
20.06.18
✎
00:04
|
(89) >Мой вывод - только прямые запросы.
Поддерживаю. >Пока правда не решил через что - АДО понятно, думал попробовать внешние источники данных Отдельная база (не 1С) и внешний источник. >Оказывается 1С ооочень сильно любит оставлять пустые и "несхлопутые" записи, особенно если включено "разделение итогов" Кто бы мог подумать! Разве только тот, кто документацию/ИТС писал... |
|||
92
Genayo
20.06.18
✎
05:54
|
(90) Агрегаты работают, после перехода с итогов на агрегаты размер базы значительно уменьшился, быстродействие точно не хуже.
|
|||
93
hhhh
20.06.18
✎
09:39
|
(90) ну у него 8.2.16. Поэтому применить все эти новшества от платформы 8.3 у него не получится. Правильно он копает в сторону SQL
|
|||
94
Антон Долгов
20.06.18
✎
10:26
|
(0) Когда ты пишешь свой запрос в SSMS, ты не используешь параметры, т.е. пишешь динамический SQL и для этого запроса формируется каждый раз новый план. 1С для запросов с условиями вызывает sp_executesql, для этих запросов если есть план в кэше, используется он.
|
|||
95
Антон Долгов
20.06.18
✎
10:39
|
(0) Но вообще, автор, ты занимаешься херней, а то что тебе предлагают тут (свои итоги, вьюхи, триггеры) - еще большая херня. Таких людей Рупасов расстреливал у стенки.
|
|||
96
VitShvets
20.06.18
✎
16:05
|
(90) Я правильно идею понимаю? Делаем регистр оборотным, вешаем агрегаты, добавляем регламентное заполнение регистра сведений как "итогов". В целевом запросе по остаткам собираем "итоги" + обороты за нужный период. Есть где почитать? Но, имхо, проще тогда уж прямые запросы. Не нужно новые сущности плодить, а запрос по сути тот-же самый - "ближние итоги плюс обороты". А в SQL и индекс можно подобрать и вообще...
(91) >> Кто бы мог подумать! Вот не надо тут. Я не сомневался, что пересчет итогов поможет, но ожидал сокращения записей не более чем на несколько десятков процентов. То, что количество записей сократились в разы, и приятное и не приятное открытие. Приятное, что помогло быстро решить локальную задачу. Неприятное, что этим надо следить и следить пристально. Через месяц буду анализировать скорость деградации, видимо писать job'ы/регламенты. (92), (93) Я что-то пропустил? Агрегаты вроде как можно только для оборотного регистра создать? Я использовал, оборотный регистр "Продажи". Отчёты, если в агрегат попадёшь, строятся очень быстро. |
|||
97
Fragster
гуру
20.06.18
✎
16:09
|
кстати, может быть проще выключить итоги по периодам и оставить только текущие итоги?
|
|||
98
VitShvets
20.06.18
✎
16:22
|
(94) Татычё?! Есть такая штука в составе средств управления сиквелом, профайлер называется. Он позволяет, в том числе "ловить" запросы генерируемые непосредственно 1С, вместе с актуальными их планами. Естественно запрос можно взять и нежно "покрутить" уже в SSMS, посмотреть как меняется его план.
(95) А поведай ка мне Антон Долгов, какие-нибудь есть идеи на тему 2-х терабайтной базы на предмет "обрезать", "ускорить" и всего-вот-этого-вот? При условии что монопольного доступа к базе есть 1-2 часа в сутки и сильно не каждый день. Или только овна на вентилятор вбросить не слабо? Не знаю с какого перепуга какой-то там Рупасов кого-то там расстреливал, это всяко не говорит о его выдающихся умственных способностях, во всяком случае в твоём изложении. |
|||
99
Genayo
20.06.18
✎
16:42
|
(96) Таки да, для оборотных агрегаты. Мы об этом и говорим :)
|
|||
100
Genayo
20.06.18
✎
16:45
|
(97) Тогда надо делать 2 базы - одну оперативную, только с текущими итогами, а другую отчетную - наоборот без текущих итогов. Ибо если в базе только с текущими итогами задать период хотябы год - помрет нафик с такими объемами, как у ТС...
|
|||
101
VitShvets
20.06.18
✎
16:55
|
(97) Не, иногда требуется посмотреть сильно прошлый период. Я попробую поиграться урезанием "старых периодов", что 8.3 умеет сама установкой минимального периода итогов. Профайлером посмотрю запросы-зависимости, попробую руками почистить. Но для начала надо понять скорость деградации таблицы итогов, особенно оперативных.
|
|||
102
VitShvets
20.06.18
✎
17:10
|
(99) Так агрегаты ещё с 8.2, если не 8.1 появились. В 8.3 добавили им интеллекта по поводу "рекомендаций" и позволили управлять из предприятия.
(100) Я думал про 2 базы - архивная и оперативная. В оперативной последние 3-6 месяцев, в архивной всё остальное. Народ работает только в оперативной, длинная отчетность формируется в архивной. Не придумал как их создать быстро и как связывать между собой на предмет актуализации архивной. Так чтобы это работало быстро. |
|||
103
Антон Долгов
20.06.18
✎
17:39
|
(98) Что именно тебе надо ускорить?
|
|||
104
Genayo
20.06.18
✎
17:43
|
(102) Объемы в сутки очень большие? РИБ не прокатит?
|
|||
105
romix
20.06.18
✎
18:00
|
(0) Смотрели стандартную обработку Все действия - стандартные обработки - управление итогами - полные возможности?
Полные возможности Режим полных возможностей позволяет получить полный доступ ко всем инструментам работы с итогами (закладка Итоги) и агрегатами (закладка Агрегаты) регистров накопления и регистров бухгалтерии. |
|||
106
VitShvets
20.06.18
✎
18:07
|
(103) Ну как обычно - проведение документов, всякие регламентные операции. Самое тяжелое, типовые 1Совые запросы, на которые я не могу никак повлиять. Это виртуальные таблицы "срез последних" и "остатки".
(104) Очень приличные. На пределе. Если будет какой-то сбой, уже есть шанс не догнать. Особенно в контексте планов роста. РИБ по функционалу меня устраивает полностью. Скорее всего будет гибрид какой-то. Метаданные и лёгкие объекты метаданных ходят РИБом, тяжелые SQL. |
|||
107
Антон Долгов
20.06.18
✎
18:11
|
(106) И какой у тебя самый медленный запрос и какой у него план? Выложи в формате sqlplan
|
|||
108
romix
20.06.18
✎
18:20
|
http://1sprogress.ru/anatomiya-registra-nakopleniya-vnutrennee-ustrojstvo-i-struktura-xraneniya.html
1С хранит текущие актуальные остатки (если поставить галку в настройках!) и хранит помесячно от сих до сих (две даты можно поставить в той же форме настроек (105). Таблицы можно пересчитать. То есть вот это надо посмотреть. Далее надо думать что там лучше по сути - регистр остатков или оборотов, закрывается ли он в 0, или там все время растет таблица остатков со временем. |
|||
109
VitShvets
20.06.18
✎
18:21
|
(107) В (0) написано. Не самый, но один из. План не выложу, но там смотреть нечего. Не интересный - более 50% кластеред индекс сик таблицы итогов в части оперативных итогов. Остальное впополам иннер джоин с времянкой-отбором и "агрегация" хэш матчем. Основное в плане, что кластеред индекс сик партиционирован, количество актуальных секций =14.
|
|||
110
romix
20.06.18
✎
18:22
|
Пересчет таблицы итогов еще нужен ибо http://catalog.mista.ru/public/177171/
|
|||
111
Антон Долгов
20.06.18
✎
18:24
|
(109) без партиционирования запрос какой тормозит и какой у него план? что побудило заняться партиционированием? может надо с этого начинать?
|
|||
112
H A D G E H O G s
20.06.18
✎
18:27
|
(109) Там остаточных предикатов точно нет?
|
|||
113
Антон Долгов
20.06.18
✎
18:30
|
(112) а додумывай сам! хрен тебе а не sqlplan, "там смотреть нечего"
|
|||
114
H A D G E H O G s
20.06.18
✎
18:35
|
Хотяяя.
Я правильно понимаю, что автор вытаскивает ВСЕ оперативные итоги, которых 50 тыс строк? |
|||
115
mistеr
20.06.18
✎
18:35
|
(102) Про схему архивная-оперативная и быструю актуализацию можно забыть. Пока 1С не разрешит использовать возможности скуля по быстрой обработке больших объемов данных средствами 1С. То есть многострочный DML.
|
|||
116
VitShvets
20.06.18
✎
18:48
|
(105), (108) Эта история работает с режима совместимости 8.3.5. У меня 8.2.
(110) Это видел, подчерпнул оттуда пару идей. (111) А разве не очевидно, что побудило? Скорость работы не устраивает. Причём основные тормоза именно в тех местах на, которые я повлиять не могу. Обычные "ВЫБРАТЬ бла-бла из ххх.Остатки". Или "ххх.СрезПоследних". (113) Нельзя выкладывать. СБ и всё такое. |
|||
117
VitShvets
20.06.18
✎
18:55
|
(112) Вот сейчас не уверен, что точно понял о чём ты. Поясни плз, что ты имеешь ввиду, на что посмотреть?
(114) Не все, 50 тысяч из нескольких миллионов. Есть кластерный индекс, в нем первое поле период, второе поле, то что участвует в отборе. |
|||
118
VitShvets
20.06.18
✎
18:57
|
(115) Да я как-то не шибко жажду спрашивать разрешения у 1С... Но мне больше нравится CDC.
|
|||
119
H A D G E H O G s
20.06.18
✎
18:58
|
(117) Отбой тревоги. Остаточный предикат работает только в диапазоне индекса. К твоей проблеме это не может относиться.
|
|||
120
H A D G E H O G s
20.06.18
✎
18:58
|
Сейчас я попытаюсь воспроизвести твои идеи.
|
|||
121
nicxxx
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) |
|||
122
mistеr
20.06.18
✎
19:00
|
(118) Не спрашивать разрешения это значит жить без поддержки и в постоянном страхе, что завтра с очередным обновлением платформы все поломается.
Есть еще вариант сделать хранилище в отдельной базе (не 1С), сделать его грамотно и юзать как внешний источник. |
|||
123
H A D G E H O G s
20.06.18
✎
19:05
|
Но вообще, цифры ты приводишь дикие.
Я грешу на непрогретый кэш. Но даже после DROPCLEANBUFFERS у меня цифры минимальны. Без всяких секционирований. |
|||
124
H A D G E H O G s
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 |
|||
125
H A D G E H O G s
20.06.18
✎
19:11
|
0,6 секунд вполне укладывается в твою 1 секунду. Но без секционирования.
Что то не так у тебя с запросом от 1С. |
|||
126
H A D G E H O G s
20.06.18
✎
19:11
|
Сейчас сделаю запрос через 1С.
|
|||
127
H A D G E H O G s
20.06.18
✎
19:21
|
Ну как бэ через 1С то совсем другой запрос получается, автор.
С вложенной таблицей и группировочкой разделенных итогов. |
|||
128
H A D G E H O G s
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 |
|||
129
H A D G E H O G s
20.06.18
✎
19:40
|
Проблема, скорее всего как раз в секциях. Он видит секции и начинает в них шарить, несмотря на индекс.
|
|||
130
vs84
20.06.18
✎
20:15
|
(0) а если в отборе не 50 тыс, а 1 тыс - план аналогичный?
|
|||
131
VitShvets
20.06.18
✎
20:23
|
(122) Это решается вьюхами. 1С спокойно себе работает с таблицами и не знает про вьюхи. Перенос данных спокойно себе работает со вьюхами и не знает про таблицы. Даже если 1С что-то поменяет в структуре хранения, актуализируем вьюхи, продолжаем работать.
(129) Сиквел хитро работает с секциями, они указаны в дереве индексов. В моём случае, т.к. он трогает все секции, я не получаю выигрыша от секционирования, "трогается" вся таблица, но по первому полю в индексе отбираются строки где Period = '5999-11-01'. |
|||
132
H A D G E H O G s
20.06.18
✎
20:28
|
Почему трогаются все секции?
|
|||
133
VitShvets
20.06.18
✎
20:30
|
(130) На сколько я понял по тестам, ключевое отличие тут равенство или другое условие. Если взять пример (128), и предположить, что организация есть второе поле кластерного индекса после периода, то запрос:
РегистрНакопления.ТоварыНаСкладах.Остатки(, Организация = &Организация) Полностью покроется кластерным индексом. Без дополнительных inner join. У меня же условие выглядит как: РегистрНакопления.МойРегистр.Остатки(, ЗаказПокупателя В (ВЫБРАТЬ ВТ1.ЗаказПокупателя ИЗ ВТ1)) Где ВТ1 таблица в одно поле, 50 тысяч записей, только ссылки на заказы. И тут уже план другой получается. Поднимается по кластерному записи только по периоду, а потом иннер-джоинятся уже с ВТ1. |
|||
134
VitShvets
20.06.18
✎
20:32
|
(132) :) Я собственно ради решения этого вопроса и тему создал. Причём берешь 1Совый запрос, меняешь совсем чуть-чуть, получаешь даже не тех-же самых данных кардинально иной результат.
|
|||
135
H A D G E H O G s
20.06.18
✎
21:07
|
(133) Вот мы и стали ближе к истине на 1 шаг.
Есть же теперь понимание того, что РегистрНакопления.МойРегистр.Остатки(, ЗаказПокупателя В (ВЫБРАТЬ ВТ1.ЗаказПокупателя ИЗ ВТ1)) использует индекс только по Периоду, без участия в нем ЗаказПокупателя ? |
|||
136
H A D G E H O G s
20.06.18
✎
21:49
|
Хех.
Сделал секционирование, как у автора и нарвался на его проблему. |
|||
137
H A D G E H O G s
20.06.18
✎
21:49
|
Щас Дима разберется.
|
|||
138
H A D G E H O G s
20.06.18
✎
22:02
|
Как только в запросе начинают использоваться параметры - секционирование не работает
|
|||
139
H A D G E H O G s
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 |
|||
140
H A D G E H O G s
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 |
|||
141
H A D G E H O G s
20.06.18
✎
22:07
|
Я бы на месте автора сходил бы на sql.ru, там бы сразу ответили, думаю.
|
|||
142
H A D G E H O G s
20.06.18
✎
22:07
|
С примерами из 139 -140
|
|||
143
Genayo
20.06.18
✎
22:12
|
(140)Интересно, что было бы на постгресе...
|
|||
144
H A D G E H O G s
20.06.18
✎
22:13
|
В 139 префикс поиска ptnid1000=1
В 140 префикс поиска ptnid1000>=1 и ptnid1000<=3 |
|||
145
H A D G E H O G s
20.06.18
✎
22:13
|
Собственно, у меня 3 секции
|
|||
146
H A D G E H O G s
20.06.18
✎
22:14
|
||||
147
H A D G E H O G s
20.06.18
✎
22:15
|
||||
148
H A D G E H O G s
20.06.18
✎
22:22
|
Немного не то, у товарища в условии - функция.
|
|||
149
H A D G E H O G s
20.06.18
✎
22:34
|
||||
151
Антон Долгов
20.06.18
✎
23:12
|
(149) т.е. ты слился?
|
|||
152
H A D G E H O G s
20.06.18
✎
23:16
|
(151) system, ты не выеживайся, расскажи лучше нам, почему ты до этого сам не дошел.
|
|||
153
H A D G E H O G s
20.06.18
✎
23:17
|
(151) Ну и статью почитай, про динамическую фильтрацию.
|
|||
154
Антон Долгов
20.06.18
✎
23:17
|
Вот интересно, какой-то чувак из Волгограда чота прочитал где-то про что-то и решил это у себя попробовать. Ок, ему простительно, он из региона и всё такое. Но ты-то Ежов, ты же сертифицированный иксперд, как ты повелся на невнятное блеяние и начал потакать хотелкам нуба?
|
|||
155
H A D G E H O G s
модератор
20.06.18
✎
23:18
|
Давай, до свидания.
|
|||
158
breezee
21.06.18
✎
03:06
|
(5) Ага, на ура...
Выбрать в () будет работать очень медленно. Если нужно обрезать данные, то лучше использовать внутреннее соединение |
|||
159
nicxxx
21.06.18
✎
08:53
|
(158) Дело не в том, как ты напишешь код запроса, а в том, какой оптимизатор построит план. Он может построить одинаковый план для inner join и in ().
|
|||
160
ERWINS
21.06.18
✎
09:51
|
РегистрНакопления.МойРегистр.Остатки(, ЗаказПокупателя В (ВЫБРАТЬ ВТ1.ЗаказПокупателя ИЗ ВТ1))
в часто приводит к скану. Лучше РегистрНакопления.МойРегистр.Остатки(, ЗаказПокупателя = &знаение) если одно значение, тогда вроде он ВСЕГДА использует индекс сик Кроме того попробуйте сделать для ВТ1 индекс по заказу, тогда возможен индекс мердж |
|||
161
toypaul
гуру
21.06.18
✎
10:00
|
"Недокументировано" лезешь в базу и хочешь чтобы 1С тебя поняла? Будь готов к тому что не поймет и "отказаться от запросов 1С"
"Есть идеи как можно повлиять на РегистрНакопления.МойРегистр.Остатки ?" есть. написать в 1С, чтобы они учли это в новых релизах |
|||
162
toypaul
гуру
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? |
|||
163
VitShvets
21.06.18
✎
12:21
|
Уххх, какая ожесточенная схватка :) А Антон Долгов, это такой местный сумасшедший? Обижаться нельзя, ибо на таких обижаться непрактично?
(139), (140) Именно так. А круче всего результат получается, если во времянку-условие добавить ещё константное поле Период со значением '5999-11-01 00:00:00' и сделать inner join по заказу+периоду с таблицей итогов. На моих данных, сейчас 0.5 секунды против 12 без секций и 6-7 секунд с секцями. |
|||
164
VitShvets
21.06.18
✎
12:25
|
(144) схожу, правда мне кажется, что там сходу посоветуют как надо запрос переписать, чтобы секции сработали. А я это и так уже знаю. Мне бы 1С заставить каким-то хитрым способом объяснить сиквелу... Но схожу. Коли будет результат, сюда отпишусь.
|
|||
165
VitShvets
21.06.18
✎
12:30
|
(158), (159) Inner join хорошо срабатывает когда соединяется с физической таблицей. Виртуальная таблица, это "select ... from (select ..." и join будет с внешним select... Т.е. отбора по заказам, в моём случае, не будет на уровне выборки из таблицы итогов.
|
|||
166
VitShvets
21.06.18
✎
12:33
|
(160) Понятно, что "ЗаказПокупателя = &знаение" будет лучше, но мне то надо по списку заказов.
Я индексирую ВТ, но у меня на времянке индекс скан получается. |
|||
167
H A D G E H O G s
21.06.18
✎
12:35
|
(166) Ты же понимаешь, что ты делаешь фигню?
|
|||
168
VitShvets
21.06.18
✎
12:36
|
(161) Я вот как раз и сопротивляюсь до последнего "недокументированному лазанью" в базу. Хочется минимальными затратами получить максимальный профит. Как обычно впрочем.
|
|||
169
VitShvets
21.06.18
✎
12:40
|
(162) 1С генерирует один запрос. Всё портит "sp_executesql", а точнее то, что оптимизатор при построении плана не учитывает значение параметров. Не уверен что это именно оно, но очень похоже на "Parameter sniffing".
|
|||
170
VitShvets
21.06.18
✎
12:41
|
(167) Ты про индексирование? Я не увидел разницу с индексами и без. По крайней мере по запросам, что рождает 1С. Это тесты всё.
|
|||
171
VitShvets
21.06.18
✎
12:43
|
(167) Есть кстати жгучее желание испить немного пенных напитков и обсудить ряд жизненноважных проблем :)
|
|||
172
Genayo
21.06.18
✎
13:03
|
(170) На 50000 записей и не увидишь...
|
|||
173
H A D G E H O G s
21.06.18
✎
13:05
|
(170) Именно.
Если ВТ велика (больше 1000 строк, конкретное значение уж не помню) - SQL не использует индекс при соединении. Ведь, чтобы использовать индекс - нужен nested loops - проход по строкам временной таблицы и для каждой строки временной таблицы - индексный поиск в виртуальной. Если строк ВТ будет много - SQL может посчитать, что проще обойти обе таблицы через mergejoin. |
|||
174
H A D G E H O G s
21.06.18
✎
13:07
|
mergejoin будет еще более вероятен, если ВТ и Виртуальная таблицы индекскированы. Но не из-за индекса, а из-за того, что таблицы УПОРЯДОЧЕНЫ по полю поиска из за наличия этого индекса.
Но, упорядочить ВТ можно, не создавая Индекс, а отсортировав, что более дешево. Индекс опять не нужен, НО. |
|||
175
H A D G E H O G s
21.06.18
✎
13:07
|
В вашем примере mergejoin использован не будет
|
|||
176
H A D G E H O G s
21.06.18
✎
13:10
|
Ибо, чтобы использовать mergejoin, нужно 2 таблицы, которых у вас пока нет, пока не выполниться поиск по Периоду из таблицы остатков.
По идее, если задать хинт на использование mergejoin, то SQL выполнит TableSpool (сохранение промежуточной таблицы в tempDB, фактически, та же временная таблица, средствами SQL) для результата отбора по периоду для таблицы остатков, дико медленную и потом сделает mergejoin с вашей временной. |
|||
177
H A D G E H O G s
21.06.18
✎
13:10
|
Поэтому, SQL сделает HashJoin
|
|||
178
H A D G E H O G s
21.06.18
✎
13:12
|
SQL построит хэштаблицу для вашей временной таблицы, затем выберет записи из таблицы остатков по периоду и обойдет эти записи, ища их строки в хэштаблице.
|
|||
179
los_hooliganos
21.06.18
✎
13:15
|
(169) Все верно. Построитель запроса не знает параметров, поэтому строит план запроса на все секции.
|
|||
180
los_hooliganos
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 Секционирование заработает и особо извращаться не надо и построитель запроса все должен учесть. |
|||
181
los_hooliganos
21.06.18
✎
13:21
|
(180) ну ес-но в CASE сам пропиши соотношения периодов и секций
|
|||
182
los_hooliganos
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 |
|||
183
VitShvets
21.06.18
✎
13:30
|
(177), (178) У меня mergejoin получается во всех вариантах.
|
|||
184
H A D G E H O G s
21.06.18
✎
13:48
|
(183) значит я что-то не учел.
|
|||
185
Fragster
гуру
21.06.18
✎
14:27
|
получается автору надо поместить остатки в ВТ, а потом её уже отбирать.
|
|||
186
H A D G E H O G s
21.06.18
✎
14:50
|
(183) Воспроизвел твою ситуацию - HashMatch
|
|||
187
H A D G E H O G s
21.06.18
✎
14:54
|
Однако я ошибся с 1000 строк ВТ.
У меня ВТ была на 30Кстрок (при 8млн. строк таблицы остатков) - был nested_loops. 30 тыс поисков по индексу в таблице остатков. Увеличил ВТ до 80Кстрок - стал hash_join. Видимо, есть какое то отношение размера внешней и внутренней таблицы. |
|||
188
VitShvets
21.06.18
✎
16:54
|
(185) Выигрыша не будет. Это тоже самое, что получить все оперативные остатки.
|
|||
189
VitShvets
21.06.18
✎
16:55
|
(186) У меня есть TRC, где в одном случае нестед лупс есть, но взял сейчас тот запрос, не получатся повторить, везде mergejoin...
|
|||
190
VitShvets
21.06.18
✎
16:56
|
(187) Вот тоже такое ощущение. Сейчас записей меньше стало, планы поменялись.
|
|||
192
Fragster
гуру
21.06.18
✎
17:07
|
(188) ну так веь ты говоришь, что у тебя все секции дергаются. а это не только оперативные остатки, но и помесячные итоги, которых в несколько (десятков) раз больше
|
|||
193
VitShvets
21.06.18
✎
17:13
|
(191) Ты зря перестал принимать такие кругленькие штучки, что тётя доктор прописала. Береги себя.
|
|||
194
VitShvets
21.06.18
✎
17:21
|
(192) Дёргаются, да, но по дереву индексов всёравно я получаю оперативные итоги, что на следующем шаге иннер джоянятся mergejoin-ом с времянкой-фильтром. Как итог, с сервера вытягиваются данные только по 50 тысячам заказов. Если делать внутреннее соединение с виртуальной таблицей или складывать остатки во времянку, а потом соединять две времянки, будет как минимум дольше на вытягивание всех итогов и/или создание временной таблицы.
|
|||
195
МихаилМ
25.06.18
✎
23:26
|
еще можно попробовать
https://msdn.microsoft.com/ru-ru/uk-an/library/ms179880(v=sql.120).aspx |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |