|   |   | 
| 
 | Секционирование регистра накопления | ☑ | ||
|---|---|---|---|---|
| 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С против прямых запросов, но уж больно не хочется этого делать. Есть идеи как можно повлиять на РегистрНакопления.МойРегистр.Остатки ? | |||
| 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 | 
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |