|
Оптимизация запроса | ☑ | ||
---|---|---|---|---|
0
goodjob
06.03.13
✎
13:57
|
Какой запрос более оптимален.
Что лучше, выбрать 1 раз из виртуальной таблицы и использовать "ВЫБОР КОГДА ТОГДА" или выбрать несколько раз из виртуальных таблиц и НЕ использовать "ВЫБОР КОГДА ТОГДА" 1) ВЫБРАТЬ Субконто1, ВЫБОР КОГДА Счет = &Счет1 ТОГДА СуммаОборотКт ИНАЧЕ 0 КОНЕЦ КАК Сумма1, ВЫБОР КОГДА Счет = &Счет2 ТОГДА СуммаОборотКт ИНАЧЕ 0 КОНЕЦ КАК Сумма2 ИЗ РегистрБухгалтерии.Хозрасчетный.Обороты(,,,Счет В (&Счет1,&Счет2)) или: 2) ВЫБРАТЬ Субконто1, Сумма(Сумма1) КАК Сумма1, Сумма(Сумма2) КАК Сумма2 ИЗ( ВЫБРАТЬ Субконто1, СуммаОборотКт КАК Сумма1, 0 КАК Сумма2 ИЗ РегистрБухгалтерии.Хозрасчетный.Обороты(,,,Счет = &Счет1) ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ Субконто1, 0 КАК Сумма1, СуммаОборотКт КАК Сумма2 ИЗ РегистрБухгалтерии.Хозрасчетный.Обороты(,,,Счет = &Счет2) ) КАК Обороты СГРУППИРОЫВТЬ ПО Субконто1 |
|||
1
Rie
06.03.13
✎
13:59
|
(0) Всяко вариант 1 лучше.
|
|||
2
goodjob
06.03.13
✎
14:01
|
(1) Чем?
|
|||
3
mikecool
06.03.13
✎
14:02
|
(0) замер производительности не предлагать?
|
|||
4
ДенисЧ
06.03.13
✎
14:03
|
(2) чем второй...
|
|||
5
Defender aka LINN
06.03.13
✎
14:03
|
(2) Тем, что запрос один а не два, не?
|
|||
6
mikecool
06.03.13
✎
14:04
|
(5) я бы без замеорв не был бы так категоричен
|
|||
7
goodjob
06.03.13
✎
14:05
|
(3) Ты прав. Надо мерить. Но если у кого то есть теоретическое обоснование - напишите, пожалуйста.
|
|||
8
mikecool
06.03.13
✎
14:07
|
(7) теория не всегда совпадает с практикой, так что - меряй.
|
|||
9
RomanYS
06.03.13
✎
14:13
|
(0) почему СГРУППИРОВАТЬ только во втором запросе?
|
|||
10
Maxus43
06.03.13
✎
14:15
|
(9) потому что в первом уже сгруппировано
|
|||
11
RomanYS
06.03.13
✎
14:17
|
(10) с чего это вдруг?
|
|||
12
Fragster
гуру
06.03.13
✎
14:18
|
(10) а если субконто одинаковые у счетов?
|
|||
13
Aprobator
06.03.13
✎
14:21
|
(6) да ладно. То ты один раз прошелся по данным и условие проверил, а то два, сначала для первого условия, потом для второго.
|
|||
14
Maxus43
06.03.13
✎
14:21
|
(11)(12) да, для чистоты надо добавить.
2 записи с одним субконто и одним счетом - сами схлопнутся, а вот разные счета нет... |
|||
15
goodjob
06.03.13
✎
14:25
|
(9) да, надо тоже добавить группировку
|
|||
16
Rie
06.03.13
✎
14:31
|
(7) Ты во втором варианте создаёшь две больших таблицы. Потом их объединяешь... Ну зачем это?
|
|||
17
goodjob
06.03.13
✎
14:31
|
Результат:
1-й запрос: 51,7 % времени 2-й запрос: 48,3 % времени И это еще без группировки. Сейчас добавлю группировку, разница еще больше будет... |
|||
18
sapphire
06.03.13
✎
14:32
|
Спор ни о чем.
Достаточно посмотреть во что вырождается первый и второй запрос. |
|||
19
RomanYS
06.03.13
✎
14:34
|
(17) при одинаковой производительности я бы оставил более чиаемый вариант, т.е. первый
|
|||
20
goodjob
06.03.13
✎
14:38
|
(18) Что ты имеешь ввиду? План запроса?
|
|||
21
sapphire
06.03.13
✎
14:39
|
(20) То, что поедет на сервер СУБД.
|
|||
22
GANR
06.03.13
✎
14:39
|
(0) Вариант ОБЪЕДИНИТЬ ВСЕ - это повторное сканирование таблицы, а считывание данных - тяжелее, чем ВЫБОР КОГДА.
|
|||
23
sapphire
06.03.13
✎
14:40
|
(20) И только потом смотреть план выполнения :)
|
|||
24
goodjob
06.03.13
✎
14:44
|
Результат с группировкой первого запроса:
1-й запрос: 56 % времени 2-й запрос: 44 % времени |
|||
25
Эстет хренов
06.03.13
✎
14:45
|
(0) "Счет В (&Счет1,&Счет2)" почему не ИЛИ ?
|
|||
26
goodjob
06.03.13
✎
14:45
|
(22) похоже зависит от количества обрабатываемых строк. В моем случае "ВЫБОР КОГДА" тяжелее
|
|||
27
goodjob
06.03.13
✎
14:47
|
(21) а как увидеть то, что поедет на сервер СУБД?
|
|||
28
goodjob
06.03.13
✎
14:54
|
(25) Если не ошибаюсь, ИЛИ в SQL преобразуются в объединения... или соединения... В общем ИЛИ будет хуже.
|
|||
29
sapphire
06.03.13
✎
14:54
|
(27) Настроить технологический журнал или разбирать файл трассы...
|
|||
30
sapphire
06.03.13
✎
14:55
|
(25) При ИЛИ не работает индекс.
|
|||
31
unregistered
06.03.13
✎
14:56
|
К слову, если Счет1 и Счет2 имеют разное количество субконто (на одном, например - одно, а на втором - два), то запрос к СУБД всё равно выродиться в запрос к двум таблицам - остатков и оборотов по счетам с одним субконто и к таблице остатков и оборотов по счетам с двумя субконто.
И почему не рассматривается вопрос с соединением: ВЫБРАТЬ ЕСТЬNULL(ХозрасчетныйОборотыПоСчету1.Субконто1, ХозрасчетныйОборотыПоСчету2.Субконто1) КАК Субконто, ЕСТЬNULL(ХозрасчетныйОборотыПоСчету1.СуммаОборотКт, 0) КАК Сумма1, ЕСТЬNULL(ХозрасчетныйОборотыПоСчету2.ВалютнаяСуммаОборотКт, 0) КАК Сумма2 ИЗ РегистрБухгалтерии.Хозрасчетный.Обороты(, , , Счет = &Счет1, , , , ) КАК ХозрасчетныйОборотыПоСчету1 ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Обороты(, , , Счет = &Счет2, , , , ) КАК ХозрасчетныйОборотыПоСчету2 ПО ХозрасчетныйОборотыПоСчету1.Субконто1 = ХозрасчетныйОборотыПоСчету2.Субконто1 УПОРЯДОЧИТЬ ПО Субконто |
|||
32
unregistered
06.03.13
✎
14:57
|
(31) * ВалютнаяСуммаОборотКт читать как СуммаОборотКт
|
|||
33
unregistered
06.03.13
✎
15:01
|
(31)* вместо ЛЕВОГО соединения ПОЛНОЕ
Что-то туплю сегодня... |
|||
34
Эстет хренов
06.03.13
✎
15:03
|
(30) действительно? это скверно, я так часто разворачиваю.
goodjob, запусти первый запрос с ИЛИ, скинь пожалуйста результат. еще если не затруднит скинь релиз 1c, и к-во строк результата, спасибо. |
|||
35
goodjob
06.03.13
✎
15:05
|
(31) таких счетов в запросе будет много, я для простоты взял два.
|
|||
36
МихаилМ
06.03.13
✎
15:09
|
для оборотов лучше указывать виды субконто.
|
|||
37
unregistered
06.03.13
✎
15:11
|
(35) Вы там часом не анализ субконто строите?
Тогда проще указать параметры виртуальной таблицы по виду субконто, выбирать в запросе одну сумму (вместо Сумма1, Сумма2,... СуммаN) и добавить в выбору поле Счет. |
|||
38
unregistered
06.03.13
✎
15:14
|
+ к (37) Озвучил бы автор задачу целиком. А то может статься, что правильное решение не имеет ни чего общего с тем, что написано в (0)...
|
|||
39
goodjob
06.03.13
✎
15:27
|
(38) Это специализированный отчет по контрагентам и договорам, в нем много показателей которые представляют из себя обороты по определенным бух. счетам. Каждый показатель - один или несколько счетов. В основном у счетов Субконто1-Контрагент, Субконто2-Договор, но не у всех.
|
|||
40
unregistered
06.03.13
✎
15:40
|
(39) >> но не у всех.
Не у всех они идут в указанном порядке или не у всех они в принципе есть? >> Это специализированный отчет Ну и делайте на СКД. Всё одним запросом с полями Счет, Контрагент, Договор, СуммаОборота. В настройках схемы в строках - контрагенты и договоры, в колонках - счета. Если хочется красоты, то можно поле Счет заменить на поле Показатель ВЫБОР КОГДА Счет = &Счет1 ТОГДА "Показатель1" КОГДА Счет = &Счет2 ТОГДА "Показатель2" КОГДА Счет В (&Счет3, &Счет4, &Счет5) ТОГДА "Показатель3" КОНЕЦ КАК НазваниеПоказателя" |
|||
41
goodjob
06.03.13
✎
15:55
|
(40) у некоторых порядок отличается, у некоторых нужно контрагента и договор вытаскивать из других мест.
Делаю на СКД. Там еще много вычисляемых полей на основе этих показателей, так что их надо иметь уже в запросе... |
|||
42
GANR
06.03.13
✎
15:59
|
(0)(22) ВАЖНО! Счет В (&Счет1,&Счет2) это условие, скорее всего, н е и с п о л ь з у е т индексы, в отличии от Счет = &Счет1 и Счет = &Счет2 во 2-м варианте. Вот поэтому 2-й вариант с ОБЪЕДИНИТЬ ВСЕ и 2-мя условиями использующими индексы быстрее... В стандартах 1С есть статья http://its.1c.ru/db/v8std#content:2149184307:1
|
|||
43
GANR
06.03.13
✎
16:00
|
(26) см. (42)
|
|||
44
Fragster
гуру
06.03.13
✎
16:01
|
(42) попутал ты что-то...
|
|||
45
GANR
06.03.13
✎
16:03
|
(44) Это из стандартов с ИТС. Например, запрос:
ВЫБРАТЬ Товар.Наименование ИЗ Справочник.Товары КАК Товар ГДЕ Артикул = "001" ИЛИ Артикул = "002" следует заменить на запрос: ВЫБРАТЬ Товар.Наименование ИЗ Справочник.Товары КАК Товар ГДЕ Артикул = "001" |ОБЪЕДИНИТЬ ВСЕ |ВЫБРАТЬ Товар.Наименование ИЗ Справочник.Товары КАК Товар ГДЕ Артикул = "002" |
|||
46
GANR
06.03.13
✎
16:05
|
(44) как это Счет В (&Счет1,&Счет2) в профайлере отображается?
|
|||
47
Fragster
гуру
06.03.13
✎
16:11
|
Счет IN (@p1, @p2)
|
|||
48
GANR
06.03.13
✎
16:12
|
индекс при (47), вероятно НЕ работает, как и при (30)
|
|||
49
sapphire
06.03.13
✎
16:18
|
(22) Ну ты и отжег :))))
|
|||
50
NicolayNN
06.03.13
✎
16:37
|
(45) "Не следует использовать ИЛИ в секции ГДЕ". Про параметры виртуальной таблицы не сказано
|
|||
51
Fragster
гуру
06.03.13
✎
16:44
|
(48) ты на план запроса посмотрел?
|
|||
52
Fragster
гуру
06.03.13
✎
16:45
|
на ИТС за ИЛИ написано
|
|||
53
GANR
06.03.13
✎
16:46
|
(51) нет, с профайлером проблема
|
|||
54
rs_trade
06.03.13
✎
16:46
|
вообще затраты на выполнение case очень малы.
|
|||
55
GANR
06.03.13
✎
16:48
|
(52) Если (47) по индексу читает, то почему-же оно медленнее ОБЪЕДИНИТЬ ВСЕ ???
|
|||
56
sapphire
06.03.13
✎
16:50
|
(54) Не всегда так.
|
|||
57
GANR
06.03.13
✎
16:56
|
(49) С а м о е смешное, что я когда-либо видел
Если СсылкаНаОбъект.ПолучитьОбъект().ЭтоНовый() Тогда ... КонецЕсли; |
|||
58
rs_trade
06.03.13
✎
17:05
|
что Счет IN (@p1, @p2), что объеденить, с большой долей вероятности сиквел эти два запроса приведет к одному виду
|
|||
59
mikecool
06.03.13
✎
17:11
|
(13) Александер, я же сказал, что не стал бы выносить однозначное решение без замеров производительности
|
|||
60
rs_trade
06.03.13
✎
17:14
|
+(59) Оптимизаторы СУБД не настолько тупы что бы два раза сканировать одни и те же данные в столь простом запросе.
|
|||
61
Avalone2010
06.03.13
✎
17:34
|
(0) Представьте что ваш код поддерживает сексуальный маньяк изврашенец, который знает где вы живете и какими тропами ходите домой. Я за первый вариант :)
|
|||
62
goodjob
09.03.13
✎
14:33
|
В итоге сделал так:
ВЫБРАТЬ Субконто1, СуммаОборотКт ПОМЕСТИТЬ Обороты ИЗ РегистрБухгалтерии.Хозрасчетный.Обороты(,,,Счет В (&Счет1,&Счет2)) ИНДЕКСИРОВАТЬ ПО Субконто1; //////////////////////////////////////////////////////////// ВЫБРАТЬ Субконто1, Сумма(Сумма1) КАК Сумма1, Сумма(Сумма2) КАК Сумма2 ИЗ( ВЫБРАТЬ Субконто1, СуммаОборотКт КАК Сумма1, 0 КАК Сумма2 ИЗ Обороты ГДЕ Счет = &Счет1 ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ Субконто1, 0 КАК Сумма1, СуммаОборотКт КАК Сумма2 ИЗ Обороты ГДЕ Счет = &Счет2 ) КАК Обороты СГРУППИРОВАТЬ ПО Субконто1 И от "ВЫБРАТЬ КОГДА ТОГДА" избавился, и обращение к виртуальной таблице одно |
|||
63
Fragster
гуру
09.03.13
✎
16:49
|
Индексироать не нужно
|
|||
64
Fragster
гуру
09.03.13
✎
16:49
|
если строк много - то не по СК, а по счету тогда уж
|
|||
65
RomanYS
09.03.13
✎
17:08
|
(62) это не может работать: ты в виртуальную таблицу счет не выбрал, а потом его в условиях используешь
|
|||
66
goodjob
10.03.13
✎
12:06
|
(64),(65) вы правы :)
|
|||
67
Ksandr
10.03.13
✎
13:07
|
(57) А самое печальное что я недавно встретил в конфе заказчика это:
Процедура УстановитьСубконто(Счет, Субконто, ВидСубконто, ЗначениеСубконто...) ... Если ТипЗнч(ВидСубконто) = Тип("Число") Тогда ... Иначе ВидСубк = ПланыВидовХарактеристик.ВидыСубконтоУпр.НайтиПоНаименованию(ВидСубконто.Наименование); ... КонецЕсли; КонецПроцедуры |
|||
68
Armando
10.03.13
✎
13:25
|
(42) "В" это SQLный IN. Использует индексы. Инфа 146%.
|
|||
69
vogenut
10.03.13
✎
18:32
|
8.3.2 пробовал? Там говорят регистр бухгалтерии ускорили, тока реструктуризация нужна
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |