Имя: Пароль:
1C
1С v8
Насколько эффективен такой запрос? (внутри)
0 Очень Любознательная
 
04.09.19
12:48
Добрый день! Есть следующий запрос:
ВЫБРАТЬ
    ПередачаОбъектовОСОсновныеСредства.ОсновноеСредство КАК ОсновноеСредство,
    ПередачаОбъектовОСОсновныеСредства.КПС КАК КПС,
    ПередачаОбъектовОСОсновныеСредства.Сумма КАК Сумма,
    ПередачаОбъектовОСОсновныеСредства.Ссылка.КФО КАК КФО,
    ПередачаОбъектовОСОсновныеСредства.Ссылка.Контрагент КАК Контрагент,
    ПередачаОбъектовОСОсновныеСредства.Ссылка.Договор КАК Договор,
    ПередачаОбъектовОСОсновныеСредства.Ссылка.Комментарий КАК Комментарий
ИЗ
    Документ.ПередачаОбъектовОС.ОсновныеСредства КАК ПередачаОбъектовОСОсновныеСредства
ГДЕ
    ПередачаОбъектовОСОсновныеСредства.Ссылка.ВидОперации В(&ВидыПередачи)
    И ПередачаОбъектовОСОсновныеСредства.Ссылка.Дата МЕЖДУ &Дата1 И &Дата2

Здесь Основные средства - ТЧ документа ПередачаОбъектовОС.
Насколько эффективно с точки зрения БД 2 точки в запросе?
Или же лучше сделать левое (внутреннее) соединение Ссылки со строками документа?
1 aleks_default
 
04.09.19
12:49
Нормально
2 aleks_default
 
04.09.19
12:50
Все равно внутреннее будет
3 ДенисЧ
 
04.09.19
13:10
(2) Левое, аднака
4 ДенисЧ
 
04.09.19
13:10
Хотя в данном случае - эквипенисуально
5 Cyberhawk
 
04.09.19
13:11
Не о том думаешь, проблемы на ровном месте выдумываешь
6 spiller26
 
04.09.19
13:18
Я бы через левое сделал.
7 Очень Любознательная
 
04.09.19
13:29
(5) Может быть да, я просто читала, что чем меньше точек, тем лучше
8 rphosts
 
04.09.19
13:32
(0) нормально, рассуждения о том что прикрутить соедиенния - от лукавого
9 Uzyf
 
04.09.19
13:37
(7) меньше точек - это в коде в циклах, а в запросах не страшно
10 Cyberhawk
 
04.09.19
13:37
(7) Если уменьшение точек достигается путем ухудшения читаемости и нагромождению текста запроса, то отнюдь не лучше. Тем более что получение реквизитов шапки из таблицы ТЧ - классика, которую никак нельзя ухудшить.
11 Очень Любознательная
 
04.09.19
13:39
(10) Спасибо Вам!
12 Максим Нижегородец
 
04.09.19
16:35
(0) Два левых и будет оптимально. Иначе на больших объёмах будут тормоза.
13 sqr4
 
04.09.19
16:45
(10) на курсах 1с рф было одно бесплатное видео, где они рассматривали пример помоему из УТ, там в типовой, получение реквизита через точку, было левым заменено, Гилев прямо спецом на это внимание обратил с формулировкой "вероятно быстрее".
14 ДенисЧ
 
04.09.19
16:50
(13) "Вероятно" определяется набором данных. Смотрится на планах запроса и нагрузочных тестах
15 spiller26
 
04.09.19
17:04
(12) По сути две таблицы затрагиваются, 1 - шапка документов, 2 - ТЧ документов.
Сначала отбираем всё в 1 (отбор по дате и виду), затем соединяем левым со 2-ой.
Ну как то так.
16 Cyberhawk
 
05.09.19
08:21
(13) Не могу придумать ситуацию, когда получение реквизита шапки из таблицы ТЧ через точку будет медленнее, чем левое присоединение этой шапки (по ссылке) и взятие реквизита шапки оттуда
17 Russiagreat
 
05.09.19
08:24
(0) (13) (14) (15)  Решил посмотреть какой на sql план запроса и был очень удивлен... Смотрите сами.

Выборка реализаций за год. План первого запроса по Гилеву и самих 1с (через соединение).

StmtText                                                                                                                                                                                                                                                                                                                  
--------                                                                                                                                                                                                                                                                                                                  
Nested Loops(Inner Join, OUTER REFERENCES:([T2].[_IDRRef], [Expr1014]) OPTIMIZED WITH UNORDERED PREFETCH)                                                                                                                                                                                                                  
  |--Nested Loops(Inner Join, OUTER REFERENCES:([T2].[_IDRRef], [Expr1013]) WITH UNORDERED PREFETCH)                                                                                                                                                                                                                      
  |    |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1010], [Expr1011], [Expr1012]))                                                                                                                                                                                                                                  
  |    |    |--Merge Interval                                                                                                                                                                                                                                                                                              
  |    |    |    |--Concatenation                                                                                                                                                                                                                                                                                          
  |    |    |         |--Compute Scalar(DEFINE:(([Expr1005],[Expr1006],[Expr1004])=GetRangeWithMismatchedTypes([@P2],NULL,(22))))                                                                                                                                                                                          
  |    |    |         |    |--Constant Scan                                                                                                                                                                                                                                                                                
  |    |    |         |--Compute Scalar(DEFINE:(([Expr1008],[Expr1009],[Expr1007])=GetRangeWithMismatchedTypes(NULL,[@P3],(42))))                                                                                                                                                                                          
  |    |    |              |--Constant Scan                                                                                                                                                                                                                                                                                
  |    |    |--Index Seek(OBJECT:([trade_copy].[dbo].[_Document6758].[_Document6758_3] AS [T2]), SEEK:([T2].[_Date_Time] > [Expr1                                                                                                                              
  |    |--Clustered Index Seek(OBJECT:([trade_copy].[dbo].[_Document6758].[PK___Documen__AC8ED0C40103DCE3] AS [T2]), SEE
  |--Clustered Index Seek(OBJECT:([trade_copy].[dbo].[_Document6758_VT7747].[_Document6758_VT7747_SK] AS [T1]), SEEK:([T1].                                                                                      

Результат количество строк: 2689056, чтений 1609052, длительность (4561, 4746, 4597 - три замера)

А вот план запроса когда через точку.

StmtText                                                                                                                                                                                                                                                                                                                                                                
--------                                                                                                                                                                                                                                                                                                                                                                
Nested Loops(Inner Join, OUTER REFERENCES:([T2].[_IDRRef], [Expr1004]) WITH UNORDERED PREFETCH)
|--Clustered Index Scan(OBJECT:([trade_copy].[dbo].[_Document6758].[PK___Documen__AC8ED0C40103DCE3] AS [T2]) //строка тут не влазит
|--Clustered Index Seek(OBJECT:([trade_copy].[dbo].[_Document6758_VT7747].[_Document6758_VT7747_SK] AS [T1]) // и тут

Результат количество строк: 2689056, чтений 1067237, длительность (4331, 4216, 4213 - три замера)

Очевидный факт, что запрос через точку не только не медленнее, но и даже быстрее.
18 Russiagreat
 
05.09.19
08:25
(17) Коряво получилось, с оформлением но главное смысл
19 Russiagreat
 
05.09.19
08:36
План через соединение
<img src=http://ipic.su/img/img7/fs/gkfy.1567661642.png />

План через точку

<img src=http://ipic.su/img/img7/fs/gkf1.1567661734.png />
20 Russiagreat
 
05.09.19
08:38
21 Russiagreat
 
05.09.19
18:52
Просто апну , почему через точку быстрее?
22 H A D G E H O G s
 
05.09.19
19:57
(21) Разные тексты запроса
23 Russiagreat
 
05.09.19
20:07
(22) Разумеется разные, этот через соединение

        "ВЫБРАТЬ
        |    РеализацияТоваровУслуг.Статус КАК Статус,
        |    РеализацияТоваровУслуг.Партнер КАК Партнер,
        |    РеализацияТоваровУслуг.Менеджер КАК Менеджер,
        |    РеализацияТоваровУслуг.ЗаказКлиента КАК ЗаказКлиента,
        |    РеализацияТоваровУслугТовары.Номенклатура КАК Номенклатура,
        |    РеализацияТоваровУслугТовары.Количество КАК Количество
        |ИЗ
        |    Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
        |        ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
        |        ПО РеализацияТоваровУслугТовары.Ссылка = РеализацияТоваровУслуг.Ссылка
        |ГДЕ
        |    РеализацияТоваровУслуг.Статус В(&Статус)
        |    И РеализацияТоваровУслуг.Дата МЕЖДУ &Дата1 И &Дата2
        |";

А второй через "точку"

        "ВЫБРАТЬ
        |    РеализацияТоваровУслугТовары.Ссылка.Статус КАК Статус,
        |    РеализацияТоваровУслугТовары.Ссылка.Партнер КАК Партнер,
        |    РеализацияТоваровУслугТовары.Ссылка.Менеджер КАК Менеджер,
        |    РеализацияТоваровУслугТовары.Ссылка.ЗаказКлиента КАК ЗаказКлиента,
        |    РеализацияТоваровУслугТовары.Номенклатура КАК Номенклатура,
        |    РеализацияТоваровУслугТовары.Количество КАК Количество
        |ИЗ
        |    Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
        |ГДЕ
        |    РеализацияТоваровУслугТовары.Ссылка.Статус В(&Статус)
        |    И РеализацияТоваровУслугТовары.Ссылка.Дата МЕЖДУ &Дата1 И &Дата2";

Но через точку выигрывает
24 Russiagreat
 
05.09.19
20:14
Первый вариант  http://ipic.su/img/img7/fs/gkfy.1567661832.png
Второй вариант  http://ipic.su/img/img7/fs/gkf1.1567661734.png
25 H A D G E H O G s
 
05.09.19
20:22
Тексты запросов в SQL почти идентичны.
Нет такого, что разные даты стоят в запросах?
26 H A D G E H O G s
 
05.09.19
20:23
(21) Правильный вопрос не
"Почему через точку быстрее"
а
"Почему разные планы запроса при идентичном текста"
27 Russiagreat
 
05.09.19
20:28
(25) Нет.  только текст запроса меняется
28 Russiagreat
 
05.09.19
20:31
(26) Вот блин в это и весь вопрос - почему?????
29 H A D G E H O G s
 
05.09.19
20:32
(27) Ткни в стрелку

http://prntscr.com/p2b6td

Что там по предполагаемым и фактическим строкам в 1-ом плане?
Вот у меня статистика мертвая, сейчас обновлю и будет план как в 2 скорее всего
30 rsv
 
05.09.19
20:34
(21) скорее так  почему в конкретном случае скан ненамного быстрее сик. Добавте данных в таблицы и скорее сик будет рулить
31 H A D G E H O G s
 
05.09.19
20:35
(30) Это очевидно и не интересно
32 rsv
 
05.09.19
20:36
без точек при соединении  видим ожидаемый сик и это норм
33 H A D G E H O G s
 
05.09.19
20:37
(32) Это не норма.
34 rsv
 
05.09.19
20:38
далее ..при скане может блокируется вся табличка ...
35 H A D G E H O G s
 
05.09.19
20:38
Обновил статистику и получил правильные, одинаковые планы для обоих вариантов
http://prntscr.com/p2b9vf
36 rsv
 
05.09.19
20:38
И бум ждать
37 H A D G E H O G s
 
05.09.19
20:39
(34) Ты почитай то внимательно ситуацию. Данные за год выбираются, 2.5 млн строк
38 rsv
 
05.09.19
20:40
(35)  :) сканов нет
39 rsv
 
05.09.19
20:42
(37) обычно выбирал с подсказкой hash join
40 rsv
 
05.09.19
20:43
Побыстрей будет
41 H A D G E H O G s
 
05.09.19
20:46
(38) Боже мой
42 H A D G E H O G s
 
05.09.19
20:46
Нуда, непривычно то олскулам с ОбластямиДанных
43 H A D G E H O G s
 
05.09.19
20:47
http://prntscr.com/p2bds6

Там поиск по ОбластиДанных=0, которая находит все записи, а реальный фильтр на остаточные предикаты -  фактически - скан
44 rsv
 
05.09.19
21:00
(42) а что делать когда статистику обновил а план не поменялся ?
45 H A D G E H O G s
 
05.09.19
21:01
(44) Думать как SQL
46 Russiagreat
 
05.09.19
21:38
(45) Мужики, прошу прощения , что сбаломутил - мой косяк. Я замер делал на коппии со всеми вытекающими.  На рабочей планы одинаковые.

https://prnt.sc/p2c1ll
47 Russiagreat
 
05.09.19
21:41
В почти 5 000 000 строк одинаково.... может и правда ну его левое - тупо текста меньше)
48 Конструктор1С
 
06.09.19
03:49
Видел как ораклоиды пишут запросы на больших БД. Они почему-то стараются все условия соединения и фильтров делать с условием "=" (равно), или приводить к виду, когда получаем равно (внутреннее соединение на равенство, например). Т.е. они вместо

SELECT
Field1, Field2, Field3
FROM Table1
WHERE Table1.Field1 IN (1,2,3)

напишут так

SELECT
Field1, Field2, Field3
FROM Table1
WHERE Table1.Field1 = 1

UNION ALL

SELECT
Field1, Field2, Field3
FROM Table1
WHERE Table1.Field1 = 2

UNION ALL

SELECT
Field1, Field2, Field3
FROM Table1
WHERE Table1.Field1 = 3

В чём сакральный смысл сих манипуляций мне не понятно
49 ILM
 
гуру
06.09.19
04:26
(48) считается что первый запрос выберет по индексу и загрузит индекс в память, а второй и следующие отработают с кэшем. Но согласно стандарту SQL оператор IN предпочтительнее.
Основная теорема систематики: Новые системы плодят новые проблемы.