Имя: Пароль:
1C
1C 7.7
v7: Даты оснований прямым запросом
0 Franchiser
 
гуру
22.03.19
18:50
Нужно получить запрос
документов с основаниями за период, а также даты оснований.
Как сделать оптимально, чтобы попасть в индекс:
1. Соединить _1SJourn с _1SJourn
или
2. Соединить _1SJourn <-> _1SCrdoc <->_1SJourn
?
1 Franchiser
 
гуру
22.03.19
18:52
Вот запрос который получился:
Declare @PERIODN Char(8)
SET @PERIODN = '20190101'

Select top 100
J.*,
TabRod.*,
JOsn.Date_Time_IdDoc as Date_Time_IdDoc_Osn
from
_1sJourn J (Nolock)
join _1scrdoc TabRod (nolock) on TabRod.mdid=0 and TabRod.ChildId = J.IdDoc
join _1sJourn JOsn (Nolock)
On  TabRod.ParentVal = 'O1  3M' +JOsn.IdDoc
Where J.Date_Time_IdDoc > @PERIODN
and J.SP652 <> '   0     0   '
2 Franchiser
 
гуру
22.03.19
19:03
Запрос 2:
Declare @PERIODN Char(8)
SET @PERIODN = '20190101'

Select top 100
J.*,
JOsn.Date_Time_IdDoc as Date_Time_IdDoc_Osn
from
_1sJourn J (Nolock)
join _1sJourn JOsn (Nolock)
On  J.SP652 =  '  3M ' +JOsn.IdDoc
Where J.Date_Time_IdDoc > @PERIODN
and J.SP652 <> '   0     0   '
3 Туц
 
23.03.19
18:33
Почему не пользуешь CHILD_DATE_TIME_IDDOC? Вроде как дату подчиненного как раз из него можно.
4 Franchiser
 
гуру
23.03.19
18:45
(3) мне нужна даты оснований, а не подчиненного
5 Туц
 
23.03.19
19:02
Ну так 1 джойн.... журнал и ссылки.. в ссылках дочерний с датой.. в журнале родитель с датой.
6 Franchiser
 
гуру
23.03.19
20:42
(4) нужные данные документов с основаниями + дата основания
7 trad
 
23.03.19
21:33
Для начала: пп 1 и 2 из(0) не соответствуют запросам 1 и 2
8 Franchiser
 
гуру
23.03.19
23:19
(7)
П.1 соответствует запросу (2),
А п. 2 соответствует запросу (1)
9 trad
 
24.03.19
09:59
"документов с основаниями за период"
Существительное "период" относится к документам или основаниям?
10 Franchiser
 
гуру
24.03.19
11:22
(9) к документам
11 Franchiser
 
гуру
24.03.19
11:24
Документы за период, основания могут быть в любой дате , в т.ч. не в указанном периоде
12 trad
 
24.03.19
11:47
(11) тогда схема - п.2 из (0)
но запрос 1 не соответствует задаче

в твоем понимании документ-основание - это родительский или подчиненный документ?
13 Franchiser
 
гуру
24.03.19
12:47
(12) родительский.

Может лучше запросе 2 использовать substring или right?
+ Добавить связь по deffype?
14 Djelf
 
24.03.19
15:46
Если я правильно понял что (0) надо, то для 1sqlite выборка ЗаявокПокупателя для Реализаций в определенном периоде, с попаданием в индекс, выглядит так.
Поправь в соответствие с со своим sql диалектом, должно взлететь.


SELECT
    ЖурналПодчиненных.IDDOCDEF||ЖурналПодчиненных.IDDOC [ДокПодчиненный :Документ]
    ,Ссылки.PARENTVAL [ДокОснование :Неопределенный]
    ,ЖурналОснований.DATE||ЖурналОснований.TIME [ДатаВремяДокОснования]
FROM Журнал AS ЖурналПодчиненных
LEFT JOIN __1S_CRDOC AS Ссылки
    ON  Ссылки.MDID='   0'
    AND Ссылки.CHILDID=ЖурналПодчиненных.IDDOC
LEFT JOIN Журнал AS ЖурналОснований
    ON ЖурналОснований.IDDOC=substr(Ссылки.PARENTVAL,7)
WHERE ЖурналПодчиненных.date BETWEEN :НачДата AND :КонДата
AND  ЖурналПодчиненных.IDDOCDEF=:ВидДокумента.Реализация
AND  ЖурналОснований.IDDOCDEF=:ВидДокумента.ЗаявкаПокупателя
15 trad
 
25.03.19
09:28
запрос (1) почти верен
вместо такой связи
TabRod.ParentVal = 'O1  3M' +JOsn.IdDoc
нужно
substring(TabRod.ParentVal, 7, 9) = JOsn.IdDoc
что бы индекс работал
16 trad
 
25.03.19
09:28
select
  jПодч.iddoc [ПодчиненныйДок $Документ],
  jПодч.iddocdef ПодчиненныйДок_вид,
  jПодч.date_time_iddoc ПозицияПодчиненногоДок,
  cast(left(jПодч.date_time_iddoc, 8) as datetime) ДатаПодчиненногоДок,
  rtrim(ltrim(jПодч.docno)) НомерПодчиненногоДок,

  jОснов.iddoc [ДокОснование $Документ],
  jОснов.iddocdef ДокОснование_вид,
  jОснов.date_time_iddoc ПозицияДокОснования,
  rtrim(ltrim(jОснов.docno)) НомерДокОснования,
  cast(left(jОснов.date_time_iddoc, 8) as datetime) ДатаДокОснования

from _1sjourn jПодч (nolock)
join _1scrdoc cr (nolock) on cr.childid = jПодч.iddoc and cr.mdid = 0
join _1sjourn jОснов (nolock) on jОснов.iddoc = substring(cr.parentval, 7, 9)
where jПодч.date_time_iddoc > '20190201'
17 trad
 
25.03.19
09:34
+
and jОснов.iddocdef = $ВидДокумента.НаименованиеВидаДокументаСКодом__3M
18 trad
 
25.03.19
09:44
и что такое SP652?
неужели общий реквизит ДокОснование с отбором?
19 Franchiser
 
гуру
25.03.19
11:27
SP652 это документ-основание.
Как определить попадаю я в индекс? Как это выглядит в плане запроса?
20 Franchiser
 
гуру
25.03.19
11:34
(14),(15),(16) спасибо, попробую
21 Franchiser
 
гуру
25.03.19
12:17
Итоговый запрос (время выполнения 1-3 сек):
Declare @PERIODN Char(9)
Declare @PERIODK Char(9)
SET @PERIODN = '20190101'
SET @PERIODK = '20190331Z'


Select top 100
J.IdDoc,
JOsn.IdDoc,
JOsn.Date_Time_IdDoc as Date_Time_IdDoc_Osn
from
_1sJourn J (Nolock)
join _1scrdoc TabRod (nolock) on TabRod.mdid=0 and TabRod.ChildId = J.IdDoc
join _1sJourn JOsn (Nolock)
On  Substring(TabRod.ParentVal,7,9) = JOsn.IdDoc and JOsn.IDDOCDEF = 130
Where J.Date_Time_IdDoc Between @PERIODN  AND @PERIODK
and J.SP652 <> '   0     0   '
and J.IDDOCDEF = 130

Для информации время выполнения запроса 1: 3 мин 33 сек, запроса 2: 6 мин 5 сек.
22 Ёпрст
 
25.03.19
13:38
(19) Это общий реквизит документов с галкой отбор ?
И тип <документ> ?
23 Ёпрст
 
25.03.19
13:39
(18) )
24 trad
 
25.03.19
13:39
(21) так тебя и подчиненные интересуют строго определенного вида?
25 trad
 
25.03.19
13:41
(21)
JOsn.IDDOCDEF = 130
J.IDDOCDEF = 130
документы одного вида друг на друга ссылаются?
26 trad
 
25.03.19
13:48
(19) "Как определить попадаю я в индекс? Как это выглядит в плане запроса?"
Главное, ты должен понимать в какой индекс собираешься попадать
В плане выполнения, в информации по вершине графа плана, смотришь аргумент.
Там будет что-то типа OBJECT(ИмяБазы.dbo.ИмяТаблицы.ИмяИндекса ...
вот и смотришь попал или нет
27 trad
 
25.03.19
13:51
(26) да и важно посмотреть по каким полям ключа индекса, индекс отработал
seek:(условия,...)
28 Franchiser
 
гуру
25.03.19
14:32
(22) Да, все верно
29 Franchiser
 
гуру
25.03.19
14:33
(25) Да, вид документа-основания и подчиненного одинаковый
30 trad
 
25.03.19
14:40
при наличии общего реквизита с отбором
Select top 100
J.IdDoc,
JOsn.IdDoc,
JOsn.Date_Time_IdDoc as Date_Time_IdDoc_Osn
from
_1sJourn J (Nolock)
join _1sJourn JOsn (Nolock)
On JOsn.IdDoc = right(J.SP652, 9)
Where J.Date_Time_IdDoc Between @PERIODN  AND @PERIODK
and J.SP652 like '  3M%'
and J.IDDOCDEF = 130
31 trad
 
25.03.19
14:41
при наличии не общего реквизита или общего без отбора, есть еще вариант с использованием таблицы документа вместо _1scrdoc
32 trad
 
25.03.19
14:42
и почему не пользоваться метапарсером?..
33 Franchiser
 
гуру
25.03.19
14:53
(32) Могу привести запрос с метапарсером (полный запрос достаточно длинный), это я тестировал в sql.
Index seek есть, но на key lookup тратится 33% времени.
34 Franchiser
 
гуру
25.03.19
14:57
Вот часть запроса с метапарсером:
SELECT
1 as Пометка,
РасходнаяНакладная.IDDOC [Документ $Документ.РасходнаяНакладная]
, $РасходнаяНакладная.СуммаВклНДС СуммаВклНДС
, $РасходнаяНакладная.НДС НДС_документа
, Cast(Left(Журнал.DATE_TIME_IDDOC, 8) AS datetime) as Дата
, MAX($РасходнаяНакладная.ТипНакладной) [ТипНакладной $Перечисление.ТипыРасходнойНакладной]
, MAX(Журнал.$ОбщийРеквизит.ДокументОснование) [ДокументОснование $Документ]
,:Ставка20 as ПравильнаяСтавка
,:Ставка18 as НеправильнаяСтавка
//, Журнал.DATE_TIME_IDDOC as Позиция
FROM _1SJOURN AS Журнал With (NOLOCK)
    join _1scrdoc TabRod (nolock) on TabRod.mdid=0 and TabRod.ChildId = Журнал.IdDoc
    join _1sJourn JOsn (Nolock)
   On  Substring(TabRod.ParentVal,7,9) = JOsn.IdDoc and JOsn.IDDOCDEF = $ВидДокумента.РасходнаяНакладная and JOsn.Date_Time_IdDoc >= :ДатаПереходаНаСтавку20
    INNER JOIN $Документ.РасходнаяНакладная AS РасходнаяНакладная With (NOLOCK) ON Журнал.IDDOC = РасходнаяНакладная.IDDOC AND Журнал.IDDocDef = $ВидДокумента.РасходнаяНакладная
    INNER JOIN $ДокументСтроки.РасходнаяНакладная AS РасходнаяНакладнаяСтроки With (NOLOCK) ON РасходнаяНакладная.IDDOC = РасходнаяНакладнаяСтроки.IDDOC
WHERE (Журнал.DATE_TIME_IDDOC BETWEEN :НачДата AND :КонДата~)
    AND ($РасходнаяНакладнаяСтроки.СтавкаНДС = :Ставка18)    
    AND Журнал.$ОбщийРеквизит.ДокументОснование <> '   0     0   '
    and Журнал.IDDOCDEF = $ВидДокумента.РасходнаяНакладная
    --Условие на ЮЛ--
GROUP BY РасходнаяНакладная.IDDOC
, $РасходнаяНакладная.СуммаВклНДС
, $РасходнаяНакладная.НДС
, Журнал.DATE_TIME_IDDOC
35 Franchiser
 
гуру
25.03.19
15:03
(30) что тут улучшено?
36 Franchiser
 
гуру
25.03.19
15:12
(30) проверил, тоже работает нормально
37 trad
 
25.03.19
15:26
(35) по сравнению с чем?
38 trad
 
25.03.19
15:28
(33) без лукапа не обойтись, если нужны поля таблицы на входящие в ключ индекса, и да - это затратная операция
39 Franchiser
 
гуру
25.03.19
15:35
(37) в последнем варианте lookup увеличился с 33 до 50 %. По времени примерно одинаково.
40 trad
 
25.03.19
15:39
(39) мне не понятно какой запрос с каким сравниваешь?
41 Franchiser
 
гуру
25.03.19
15:52
Сравниваю (30) и (21)
42 Ёпрст
 
25.03.19
16:03
group by какой-то бестолковый
43 Ёпрст
 
25.03.19
16:06
а.. вижу, бестолкоый фильтр на таб часть и ставку ндс
44 Ёпрст
 
25.03.19
16:06
можно выкинуть group by и хотя бы exists влепить в where
45 trad
 
25.03.19
16:55
(41) в 30 не используется crdoc и должно быть меньше чтений страниц
46 trad
 
25.03.19
16:58
(39) "lookup увеличился с 33 до 50 %"
Это ведь еще можно так трактовать: нагрузка на лукап не выросла, просто остальные операции улучшились.
Нужно смотреть не только относительные показатели но абсолютные
47 Djelf
 
25.03.19
17:52
(34) А итоги по колонкам с какими то Суммами в РасходнаяНакладная есть?
Если есть - можно попробовать отсечь часть документов, если в них вообще нет Ставки НДС18.
ИМХО Это будет быстрее чем табличные части перебирать.
48 Туц
 
25.03.19
19:26
Судя по синтаксису база MSSQL. Добавь нужный тебе индекс в нужную тебе таблицу. А чтоб не вносить его после каждой реструктуризации, хэшируй MD файл и сравнивай с сохранённым в константе и пересоздавай его.
49 Franchiser
 
гуру
25.03.19
22:29
(44) exists вроде медленнее работать должен
50 Franchiser
 
гуру
26.03.19
00:22
(48) есть 3 нетипичных индекса, которые пересоздаются после реструктуризации отдельной обработкой.
Объясни подробнее, что значит хэшировать md и как пересоздать после реструктуризации?
51 Franchiser
 
гуру
26.03.19
00:49
(48) может быть ты про пересоздание файла DDS и индексы в нем?
52 Туц
 
26.03.19
05:56
(50)


Процедура ПриНачалеРаботыСистемы()

    бла бла бла

    MetaDataWork=СоздатьОбъект("MetaDataWork");
    MDHash = СокрЛП(СервисFormEx.ПолучитьХэшМД5(КаталогИБ()+"1cv7.md",1));  
    Если СокрЛП(Константа.MDHash) <> MDHash Тогда
        ТекстЗапроса = "CREATE UNIQUE NONCLUSTERED INDEX бла бла бла ";
        глВыполнитьЗапрос(глБДЗапрос,ТекстЗапроса);
        Константа.MDHash = MDHash;    
    КонецЕсли;
    бла бла бла

КонецПроцедуры

отполируй под себя
53 Franchiser
 
гуру
26.03.19
11:01
(52) ок, примерно тоже самое сейчас делается вручную. Ещё файл DDS кажется исправляется
54 Mikeware
 
26.03.19
11:02
(53) словарь исравлять не надо.
55 Franchiser
 
гуру
26.03.19
11:07
(54) (52) master.sp_statistics доработаны?
56 Mikeware
 
26.03.19
11:13
(55) у меня не было доработано. но у меня и клюшек уже, считай, нет.
57 Franchiser
 
гуру
26.03.19
12:17
Если просто добавить индексы то 7ка не запускается. Нужно или править DDS, или дорабатывать sp_statistics
58 Mikeware
 
26.03.19
12:30
(57) все прекрасно запускалось. и с добавленными индексами, и с добавленными таблицами, и с триггерами... можно вообще словарь на левый подменить - и все будет работать, пока не потребуется реструктуризация.