|   |   | 
| 
 | Какой запрос оптимальнее | ☑ | ||
|---|---|---|---|---|
| 0
    
        posq 06.10.14✎ 11:05 | 
        Не могу решить какой запрос оптимальнее подскажите. К сожалению по оптимальности теорию прочитал, а вывод сделать не могу. Тесты в силу определенный причин провести не могу.
 Задача: Есть Справочник с табличной частью, необходимо выбрать элемент справочника у которого реквизит в "шапке" удовлетворяет условию и в табличной части есть запись с удовлетворяющая условию. Оригинал (с моей точки зрения не оптимален): ВЫБРАТЬ ДомаПоДоговору.Дом КАК Дом, ДомаПоДоговору.Ссылка КАК Договор, ДомаПоДоговору.Ссылка.Сумма КАК Сумма, ДомаПоДоговору.Ссылка.ПредметДоговора КАК ПредметДоговора ИЗ Справочник.ДоговорыЖКХ.Дома КАК ДомаПоДоговору ГДЕ ДомаПоДоговору.Дом = &Ссылка И ДомаПоДоговору.Ссылка.Владелец = &ЖКХ ////////////////////////////////////////////////////////////////// Мой вариант 1: ВЫБРАТЬ ДомаПоДоговору.Дом КАК Дом, ДоговорыЖКХ.Ссылка, ДоговорыЖКХ.Сумма КАК Сумма, ДоговорыЖКХ.ПредметДоговора КАК ПредметДоговора, ДоговорыЖКХ.НомерДоговора, ДоговорыЖКХ.ДатаДоговора ИЗ Справочник.ДоговорыЖКХ.Дома КАК ДомаПоДоговору ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ДоговорыЖКХ КАК ДоговорыЖКХ ПО ДомаПоДоговору.Ссылка = ДоговорыЖКХ.Ссылка ГДЕ ДомаПоДоговору.Дом = &Дом И ДоговорыЖКХ.Владелец = &ЖКХ ///////////////////////////////////////////////////////////////////// Мой вариант 2: ВЫБРАТЬ ДоговорыПоЖКХ.Ссылка, ДоговорыПоЖКХ.Сумма, ДоговорыПоЖКХ.ПредметДоговора, ДоговорыПоЖКХ.НомерДоговора, ДоговорыПоЖКХ.ДатаДоговора ИЗ (ВЫБРАТЬ ДомаПоДоговору.Ссылка КАК Ссылка ИЗ Справочник.ДоговорыЖКХ.Дома КАК ДомаПоДоговору ГДЕ ДомаПоДоговору.Дом = &Дом) КАК ДоговорыПоДому ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ ДоговорыЖКХ.Ссылка КАК Ссылка, ДоговорыЖКХ.Сумма КАК Сумма, ДоговорыЖКХ.ПредметДоговора КАК ПредметДоговора, ДоговорыЖКХ.НомерДоговора КАК НомерДоговора, ДоговорыЖКХ.ДатаДоговора КАК ДатаДоговора ИЗ Справочник.ДоговорыЖКХ КАК ДоговорыЖКХ ГДЕ ДоговорыЖКХ.Владелец = &ЖКХ) КАК ДоговорыПоЖКХ ПО ДоговорыПоДому.Ссылка.Ссылка = ДоговорыПоЖКХ.Ссылка | |||
| 1
    
        Ёпрст гуру 06.10.14✎ 11:07 | 
        (0) то что оригинал     | |||
| 2
    
        posq 06.10.14✎ 11:07 | 
        Будет ли мой "не красивый" первый вариант "оптимальнее" оригинала?
 И действительно ли мой второй вариант лучше двух предыдущих? Есть ли смысл оптимизировать? | |||
| 3
    
        Maxus43 06.10.14✎ 11:08 | 
        Оригинал.
 Следующие варианты УГ какое-то | |||
| 4
    
        Maxus43 06.10.14✎ 11:09 | 
        хотя по условию тут можно ещё логически подумать...
 ГДЕ ДомаПоДоговору.Дом = &Ссылка И ДомаПоДоговору.Ссылка.Владелец = &ЖКХ разве один Дом может быть у разных ЖКХ? лишнее условие имхо | |||
| 5
    
        posq 06.10.14✎ 11:09 | 
        Первый вариант красивее внешне согласен. 
 Но везде же пишут что обращение через точку это очень плохо?) | |||
| 6
    
        mergan 06.10.14✎ 11:10 | 
        не понятно для чего в простых запросах по одной таблице лепить соединения     | |||
| 7
    
        Ёпрст гуру 06.10.14✎ 11:10 | 
        (2) нет     | |||
| 8
    
        Maxus43 06.10.14✎ 11:11 | 
        (5) выбор из Вложенного запроса - плохо.
 Через точку не плохо, это просто превращается в вариант с соединением, и это надо помнить. К составному типу через точку - вот засада | |||
| 9
    
        posq 06.10.14✎ 11:12 | 
        Я всю жизнь писал так как в первом варианте, но во всех мануалах по оптимизации пишут что обращение через точку - ужасно)     | |||
| 10
    
        hhhh 06.10.14✎ 11:12 | 
        (5) во втором варианте система всё равно делает через точку. ТОлько без вашего ведома. Что еще хуже.     | |||
| 11
    
        Maxus43 06.10.14✎ 11:13 | 
        ПО ДоговорыПоДому.Ссылка.Ссылка = ДоговорыПоЖКХ.Ссылка
 забыл ты дописать ещё .Ссылка.Ссылка.Ссылка.Ссылка.Ссылка.Ссылка.Ссылка.Ссылка.Ссылка.Ссылка.Ссылка.Ссылка.Ссылка.Ссылка.Ссылка.Ссылка | |||
| 12
    
        DirecTwiX 06.10.14✎ 11:13 | 
        (5) Там за точкой только одна таблица скрывается - будет только одно соединение, а не несколько. Это нормально.     | |||
| 13
    
        hhhh 06.10.14✎ 11:13 | 
        (10)+ нет, наоборот, в первом варианте система вместо точки подставляет соединение.     | |||
| 14
    
        Лодырь 06.10.14✎ 11:14 | 
        (9) Обращение ужасно, если  у тебя идет неявное соединение с несколькими таблицами при составном типе. А так - ничего ужасного не произойдет.     | |||
| 15
    
        posq 06.10.14✎ 11:15 | 
        (8) Про составные типы ясно.
 Но у Чистова на сайте и не только у него слышал что если пишем обращение через точку СУБД его превратит в соединение и что если пишем, то лучше самим написать обращение к таблице. (11) Это просто описка. | |||
| 16
    
        боксер 06.10.14✎ 11:17 | 
        (0)а проверить, если так паришься проблема?
 сделай цикл тыщу раз вызови разные варианты и время замерь. сравни. чем больше тестов тем корректнее сравнение | |||
| 17
    
        Maxus43 06.10.14✎ 11:19 | 
        (15) в данном случае не соглашусь, в таких простых примерах монопесуально как напишешь     | |||
| 18
    
        posq 06.10.14✎ 11:19 | 
        Просто теории начитался(в т.ч. и от сюда http://kb.1c.ru/articleView.jsp?id=44) теперь пытаюсь применять, но столько доп. вопросов возникать начинает, что можно так или иначе переписать запрос.     | |||
| 19
    
        posq 06.10.14✎ 11:20 | 
        (17) Ясно.     | |||
| 20
    
        Maxus43 06.10.14✎ 11:22 | 
        (18) Не усложняй без необходимости, тут главное ключевые места правильно писать, типа как с составными     | |||
| 21
    
        posq 06.10.14✎ 11:27 | 
        Еще вопрос ускоряет ли выборку описание условий к виртуальной таблице через "выбор когда.." или можно все написать через "И".
 Например вот так: ВЫБРАТЬ ВЫРАЗИТЬ(СостоянияДокументовСрезПоследних.Документ КАК Документ.ЗапросНаОбслуживание) КАК Документ, МАКСИМУМ(СостоянияДокументовСрезПоследних.Период) КАК Период ПОМЕСТИТЬ ОтобранныеДокументыДокументы ИЗ РегистрСведений.СостоянияДокументов.СрезПоследних( &ТекущаяДата, ВЫБОР КОГДА Документ ССЫЛКА Документ.ЗапросНаОбслуживание ТОГДА ВЫБОР КОГДА НЕ ВЫРАЗИТЬ(Документ КАК Документ.ЗапросНаОбслуживание).Состояние = ЗНАЧЕНИЕ(Справочник.СостоянияДокументов.Закрыт) ТОГДА ВЫБОР КОГДА РАЗНОСТЬДАТ(Период, &ТекущаяДата, ЧАС) > &ЛимитВремени ТОГДА ВЫБОР КОГДА ВЫРАЗИТЬ(Документ КАК Документ.ЗапросНаОбслуживание).ВидЗапроса = ЗНАЧЕНИЕ(Перечисление.ВидыЗапросовНаОблсуживание.УстранениеСбоя) ТОГДА ВЫБОР КОГДА ВЫРАЗИТЬ(Документ КАК Документ.ЗапросНаОбслуживание).Клиент.ЮрФизЛицо = ЗНАЧЕНИЕ(Перечисление.ТипыКлиентов.ЮридическоеЛицо) ТОГДА ВЫБОР КОГДА ВЫРАЗИТЬ(Документ КАК Документ.ЗапросНаОбслуживание).Клиент.Приоритет В (&МассивПриоритетов) ТОГДА ИСТИНА ИНАЧЕ ЛОЖЬ КОНЕЦ ИНАЧЕ ЛОЖЬ КОНЕЦ ИНАЧЕ ЛОЖЬ КОНЕЦ ИНАЧЕ ЛОЖЬ КОНЕЦ ИНАЧЕ ЛОЖЬ КОНЕЦ ИНАЧЕ ЛОЖЬ КОНЕЦ) КАК СостоянияДокументовСрезПоследних СГРУППИРОВАТЬ ПО ВЫРАЗИТЬ(СостоянияДокументовСрезПоследних.Документ КАК Документ.ЗапросНаОбслуживание) ; | |||
| 22
    
        hhhh 06.10.14✎ 11:36 | 
        (21) наоборот, замедляет     | |||
| 23
    
        Зеленый пень 06.10.14✎ 11:37 | 
        (21) Мощное условие (так вот почему в ЖКХ так медленно все работают - ждут результатов из БД:) ) !
 По теме: подозрение на неправильную структуру регистра, почему не используются данные регистра для условий? И непонятно, зачем вообще в данном случае регистр, если всё строится по одному виду документа? А при большом размере БД СрезПоследних() загнется с таким запросом. | |||
| 24
    
        zak555 06.10.14✎ 11:37 | 
        (21) xnj 'nj &     | |||
| 25
    
        zak555 06.10.14✎ 11:37 | 
        *что это ?     | |||
| 26
    
        DirecTwiX 06.10.14✎ 11:47 | 
        (21) Разные случае бывают. Можешь замедлить выборку, если неправильный порядок укажешь.
 Но пример какой-то страшный -.- | |||
| 27
    
        zak555 06.10.14✎ 11:48 | 
        (21) не проще это переписать ?     | |||
| 28
    
        qwerty 06.10.14✎ 11:53 | 
        Можно попробовать сначала выбрать все договора по владельцу во временную таблицу. Но не думаю что это будет оптимальнее, чем оригинал.     | |||
| 29
    
        qwerty 06.10.14✎ 11:55 | 
        А вообще, профайлер в руки. Попробуй все варианты, вибери оптимальный, сделай выводы.     | |||
| 30
    
        posq 06.10.14✎ 12:18 | 
        (22) Т.е. лучше через "И"?
 (23) Необходимо поле "период" из регистра, но не в этом дело. Вопрос в том ускоряет или наоборот и почему. Объем записей в регистре приличный. (27) Переписать через "И"? (28) Попробую, но сейчас вопрос именно в теории. Смысл вопроса как раз в том в любых запросах ускоряет ли такое написание или нет. Я самым последним поместил, по моему мнению, самое тяжелое сравнение. Есть ли смысл? | |||
| 31
    
        DirecTwiX 06.10.14✎ 12:21 | 
        (30) В любых не ускоряет. В некоторых - ускоряет.
 Самое тяжелое писать в конец имеет смысл. | |||
| 32
    
        zak555 06.10.14✎ 12:23 | 
        (30) что там трудного ?
 тебе нужно отобрать данные из таблицы Документ.ЗапросНаОбслуживание, где Состояние != Закрыт и с ней работать | |||
| 33
    
        posq 06.10.14✎ 12:33 | 
        (32) На оборот любой роме закрыт 
 НЕ ВЫРАЗИТЬ(Документ КАК Документ.ЗапросНаОбслуживание).Состояние = ЗНАЧЕНИЕ(Справочник.СостоянияДокументов.Закрыт) В документе нигде не хранится время последнего изменения состояния. Дата документа <> "время изменения последнего состояния". | |||
| 34
    
        Зеленый пень 06.10.14✎ 12:33 | 
        (30) " ускоряет или наоборот" - по сравнению с чем?
 Если играться аналогичными условиями внутри вирт.таблицы, это кардинально ничего не изменит. Надо понимать, как SQL строит сам СрезПоследних - это очень тяжелый запрос, и он в процессе посторения среза к каждой записи будет применять всё это тяжелое условие. Ухищрения с условиями в конкретном случае - попытка выиграть жалкие проценты, в то время как можно ускорить работу на порядок, переписав запрос. | |||
| 35
    
        posq 06.10.14✎ 14:09 | 
        Еще возник вопрос абстрагируясь от сути(таблицы только как пример): Какой запрос будет работать быстрее?
 Верно ли я понимаю, что второй случай лучше т.к. мы сначала выберем необходимые данные по отборам, а потом их свяжем. В первом же сначала произойдет соединение всех записей в таблице, а потом уже проверка на соответствие отборам? Это же очевидно или я очень сильно заблуждаюсь?) Мой вариант 1: ВЫБРАТЬ ДомаПоДоговору.Дом КАК Дом, ДоговорыЖКХ.Ссылка, ДоговорыЖКХ.Сумма КАК Сумма, ДоговорыЖКХ.ПредметДоговора КАК ПредметДоговора, ДоговорыЖКХ.НомерДоговора, ДоговорыЖКХ.ДатаДоговора ИЗ Справочник.ДоговорыЖКХ.Дома КАК ДомаПоДоговору ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ДоговорыЖКХ КАК ДоговорыЖКХ ПО ДомаПоДоговору.Ссылка = ДоговорыЖКХ.Ссылка ГДЕ ДомаПоДоговору.Дом = &Дом И ДоговорыЖКХ.Владелец = &ЖКХ ///////////////////////////////////////////////////////////////////// Мой вариант 2: ВЫБРАТЬ ДоговорыПоЖКХ.Ссылка, ДоговорыПоЖКХ.Сумма, ДоговорыПоЖКХ.ПредметДоговора, ДоговорыПоЖКХ.НомерДоговора, ДоговорыПоЖКХ.ДатаДоговора ИЗ (ВЫБРАТЬ ДомаПоДоговору.Ссылка КАК Ссылка ИЗ Справочник.ДоговорыЖКХ.Дома КАК ДомаПоДоговору ГДЕ ДомаПоДоговору.Дом = &Дом) КАК ДоговорыПоДому ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ ДоговорыЖКХ.Ссылка КАК Ссылка, ДоговорыЖКХ.Сумма КАК Сумма, ДоговорыЖКХ.ПредметДоговора КАК ПредметДоговора, ДоговорыЖКХ.НомерДоговора КАК НомерДоговора, ДоговорыЖКХ.ДатаДоговора КАК ДатаДоговора ИЗ Справочник.ДоговорыЖКХ КАК ДоговорыЖКХ ГДЕ ДоговорыЖКХ.Владелец = &ЖКХ) КАК ДоговорыПоЖКХ ПО ДоговорыПоДому.Ссылка.Ссылка = ДоговорыПоЖКХ.Ссылка | |||
| 36
    
        КонецЦикла 06.10.14✎ 14:13 | 
        SQL умнее тебя. Он сделает все так как ты и не догадывался.
 А если серьезно - найди время и возможность посмотреть лично планы выполнения запросов, не ипи моск. | |||
| 37
    
        hhhh 06.10.14✎ 14:18 | 
        (35) по любому 
 ПО ДоговорыПоДому.Ссылка.Ссылка в 10 раз медленнее чем ПО ДоговорыПоДому.Ссылка Зачем вы влезаете в какие-то тонкости, если элементарное не можете освоить? | |||
| 38
    
        posq 06.10.14✎ 14:19 | 
        (37) Это описка. И так ясно. Просто скопировал из первого поста.     | |||
| 39
    
        posq 06.10.14✎ 14:23 | 
        (36) Ок. Я понимаю что оптимизатор запроса сам напишет как лучше. Очевидная же вещь. В Первом случае у нас сначала будет соединение двух полных таблиц, а потом отбор? Или ситуация такая что делать можно как хочешь и хрен проссышь как этот запрос на SQL переведется?     | |||
| 40
    
        posq 06.10.14✎ 14:24 | 
        (37)В конструкторе по быстрому накидывал вот и вылезла ссылка.     | |||
| 41
    
        hhhh 06.10.14✎ 14:31 | 
        всё-таки
 ВЫБРАТЬ ДомаПоДоговору.Дом КАК Дом, ДомаПоДоговору.Ссылка, ДомаПоДоговору.Ссылка.Сумма КАК Сумма, ДомаПоДоговору.Ссылка.ПредметДоговора КАК ПредметДоговора, ДомаПоДоговору.Ссылка.НомерДоговора, ДомаПоДоговору.Ссылка.ДатаДоговора ИЗ Справочник.ДоговорыЖКХ.Дома КАК ДомаПоДоговору ГДЕ ДомаПоДоговору.Дом = &Дом И ДомаПоДоговору.Ссылка.Владелец = &ЖКХ | |||
| 42
    
        floody 06.10.14✎ 14:34 | 
        Оригинал конечно лучше, читабельность тоже важна.
 Вот если запрос реально тормозит, тогда да, в топку читабельность. | |||
| 43
    
        hhhh 06.10.14✎ 14:36 | 
        (39) похоже вы забыли указать у поля ДомаПоДоговору.Дом свойство "Индексировать". Из-за этого и пристаете к нам со всякой лабудой.     | |||
| 44
    
        posq 06.10.14✎ 14:40 | 
        Я про конкретику не говорю. Просто пример абстрактных двух таблиц с огромным количеством данных, я ни с чем не пристаю пытаюсь понять как лучше, быстрее, логичнее и в последнюю очередь читабельнее.
 Да, в курсе что индексы важны, по владельцу, вон есть индекс. Сейчас вопрос стоит в (35). | |||
| 45
    
        hhhh 06.10.14✎ 14:42 | 
        (44) ну за вложенные запросы по-любому на экзамене расстреливают. Прям из калаша вгоняют 150 пуль. Чтобы больше не писал.     | |||
| 46
    
        Sammo 06.10.14✎ 14:49 | 
        (42) Мне наоборот читабельнее запрос с соединением :)     | |||
| 47
    
        Hans 06.10.14✎ 14:52 | 
        Не надо мудрить, оставьте оригинал, он читабельный.     | |||
| 48
    
        sf 06.10.14✎ 14:52 | 
        (44) то, что первый запрос быстрее будет, было уже?     | |||
| 49
    
        posq 06.10.14✎ 15:13 | 
        (44) Да.
 (45) Да я в одном месте слышал что под временную таблицу создается создается реальная таблица, а это время и ресурсы, в другом месте что оптимизатор нормально не сможет вычислить количество получаемых записей в таблице формируемой подзапросом и оптимально построить запрос для соединения таблиц. В случае если есть соединение, то необходимо пользоваться временными таблицами. Верно? | |||
| 50
    
        sf 06.10.14✎ 15:24 | 
        (49) В случае если есть соединение, то необходимо пользоваться временными таблицами.
 имхо, в этом случае надо обратно в книжки учить терминологию. и не фантазировать по поводу как себя поведет скуль. хотя это тоже было, да? | |||
| 51
    
        DexterMorgan 06.10.14✎ 15:50 | 
        (50) "и не фантазировать по поводу как себя поведет скуль"
 именно поэтому в книжках и рекомендуют вместо соединений с вложенными запросами или виртуальными таблицами использовать временные таблицы | |||
| 52
    
        sf 06.10.14✎ 15:53 | 
        (51) что? задачу в (0) еще и через временные таблицы можно решить? :D     | |||
| 53
    
        roman52 06.10.14✎ 21:30 | 
        ВЫБРАТЬ
 ДомаПоДоговору.Дом КАК Дом, ДоговорыЖКХ.Ссылка, ДоговорыЖКХ.Сумма КАК Сумма, ДоговорыЖКХ.ПредметДоговора КАК ПредметДоговора, ДоговорыЖКХ.НомерДоговора, ДоговорыЖКХ.ДатаДоговора ИЗ Справочник.ДоговорыЖКХ.Дома КАК ДомаПоДоговору ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ДоговорыЖКХ КАК ДоговорыЖКХ ПО ДомаПоДоговору.Ссылка = ДоговорыЖКХ.Ссылка И ДомаПоДоговору.Дом = &Дом И ДоговорыЖКХ.Владелец = &ЖКХ имхо куда уж быстрее.. | |||
| 54
    
        User_Agronom 06.10.14✎ 21:43 | 
        (15)...Но у Чистова на сайте и не только у него слышал что если пишем обращение через точку СУБД его превратит в соединение... 
 Интересно,откуда у Чистова такие выводы? (15)...что если пишем, то лучше самим написать обращение к таблице... Чушь чистой воды, особенно если первая часть (про превращение в соединение) правда. | |||
| 55
    
        КонецЦикла 06.10.14✎ 21:44 | 
        (54) А во что можно еще превратить точку?     | |||
| 56
    
        roman52 06.10.14✎ 21:49 | 
        (54) СУБД обращение через точку в любом случае превратит в левое соединение
 а сам можеть написать через внутреннее разницу чуйствуешь? | |||
| 57
    
        User_Agronom 06.10.14✎ 21:59 | 
        (56) Ссыль на сайт разработчиков СУБД. MS или Postgre. На основании чего были сделаны такие выводы?     | |||
| 58
    
        MrStomak 06.10.14✎ 22:06 | 
        (57) Зачем тебе ссыль на разработчиков СУБД, в языках которых никакого "обращения через точку" вообще не допустимо?
 Попробуй через точку поле регистратора у вт ОстаткиИОбороты получить и объяснить, как без левого соединения там null могут быть. А еще лучше просто посмотреть в профайлере. | |||
| 59
    
        User_Agronom 06.10.14✎ 22:14 | 
        http://technet.microsoft.com/ru-ru/magazine/2007.11.sqlquery.aspx
 SELECT c.CustomerID, SUM(LineTotal) FROM Sales.SalesOrderDetail od JOIN Sales.SalesOrderHeader oh ON od.SalesOrderID=oh.SalesOrderID JOIN Sales.Customer c ON oh.CustomerID=c.CustomerID GROUP BY c.CustomerID я вижу точку. Как это соотносится с (58)...в языках которых никакого "обращения через точку" вообще не допустимо?... ? И сайт не жёлтой прессы;) | |||
| 60
    
        MrStomak 06.10.14✎ 22:31 | 
        (59) Ну давай покажи, где ты тут увидел "обращение через точку".     | |||
| 61
    
        roman52 06.10.14✎ 22:56 | 
        (57) пардоньте, не СУБД, а движок 1С при трансляции запросов 1С в запросы СУБД
 а вообще лучше один раз увидеть... профайлер в руки и впердё - все вопросы должны отпасть | |||
| 62
    
        User_Agronom 07.10.14✎ 08:43 | 
        (60) SELECT c.CustomerID     | |||
| 63
    
        roman52 07.10.14✎ 20:40 | 
        (60) 
 http://www.fedupusa.org/wp-content/uploads/2013/11/1314029819767.png еще раз, прогони запросы ТС-а через профайлер и посмотри получающиеся тексты запросов SQL - все прояснится | |||
| 64
    
        roman52 07.10.14✎ 20:41 | 
        (63) к (62)     | |||
| 65
    
        Drac0 07.10.14✎ 20:48 | 
        (62) Это не "обращение через точку". Это обращение к полю "CustomerID" таблицы с псевдонимом "с". А вот если бы там было что-то типа с.Customer.Name, тогда да. Странно, что ты это не понимаешь.     | 
 
 | Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |