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