Имя: Пароль:
1C
1С v8
Производительность запросов
0 AllJoke
 
29.10.13
11:17
Всем день добрый. Вот на день грядущий решил запросы поделать. Запустил замер производительности. И задумался....

Есть два запроса

Запрос1:

Запрос = Новый Запрос;
        Запрос.Текст = "ВЫБРАТЬ
        |    Номенклатура.ШтрихКод КАК ШтрихКод,
        |    РазмерыРучнойКлади.Авиакомпания.Код КАК КодАвиакомпании,
        |    ВЫБОР
        |        КОГДА Номенклатура.Габарит1 = 0
        |                И Номенклатура.Габарит2 = 0
        |                И Номенклатура.Габарит3 = 0
        |            ТОГДА ЛОЖЬ
        |        ИНАЧЕ ИСТИНА
        |    КОНЕЦ КАК ГабаритыЗаполнены,
        |    ВЫБОР
        |        КОГДА РазмерыРучнойКлади.Габарит1 = 0
        |                И РазмерыРучнойКлади.Габарит2 = 0
        |                И РазмерыРучнойКлади.Габарит3 = 0
        |            ТОГДА ИСТИНА
        |        ИНАЧЕ ВЫБОР
        |                КОГДА Номенклатура.Габарит1 <= РазмерыРучнойКлади.Габарит1
        |                        И Номенклатура.Габарит2 <= РазмерыРучнойКлади.Габарит2
        |                        И Номенклатура.Габарит3 <= РазмерыРучнойКлади.Габарит3
        |                    ТОГДА ИСТИНА
        |                ИНАЧЕ ЛОЖЬ
        |            КОНЕЦ
        |    КОНЕЦ КАК Габариты,
        |    ВЫБОР
        |        КОГДА РазмерыРучнойКлади.СуммаГабаритов = 0
        |            ТОГДА ИСТИНА
        |        ИНАЧЕ ВЫБОР
        |                КОГДА Номенклатура.Габарит1 + Номенклатура.Габарит2 + Номенклатура.Габарит3 <= РазмерыРучнойКлади.СуммаГабаритов
        |                    ТОГДА ИСТИНА
        |                ИНАЧЕ ЛОЖЬ
        |            КОНЕЦ
        |    КОНЕЦ КАК СуммаГабаритов
        |ИЗ
        |    Справочник.Номенклатура КАК Номенклатура,
        |    РегистрСведений.РазмерыРучнойКлади КАК РазмерыРучнойКлади
        |ГДЕ
        |    Номенклатура.КатегорияТовара.ПроверятьРазмерыРучнойКлади = ИСТИНА
        |    И Номенклатура.ФлагИнтерМаг = 1
        |
        |УПОРЯДОЧИТЬ ПО
        |    ШтрихКод
        |АВТОУПОРЯДОЧИВАНИЕ";
        РезультатЗапроса = Запрос.Выполнить();

Запрос2:
Запрос = Новый Запрос;
        Запрос.Текст = "ВЫБРАТЬ
                       |    Номенклатура.ШтрихКод КАК ШтрихКод,
                       |    РазмерыРучнойКлади.Авиакомпания.Код КАК КодАвиакомпании,
                       |    ВЫБОР
                       |        КОГДА Номенклатура.Габарит1 = 0
                       |                И Номенклатура.Габарит2 = 0
                       |                И Номенклатура.Габарит3 = 0
                       |            ТОГДА ЛОЖЬ
                       |        ИНАЧЕ ИСТИНА
                       |    КОНЕЦ КАК ГабаритыЗаполнены,
                       |    ВЫБОР
                       |        КОГДА РазмерыРучнойКлади.Габарит1 = 0
                       |                И РазмерыРучнойКлади.Габарит2 = 0
                       |                И РазмерыРучнойКлади.Габарит3 = 0
                       |            ТОГДА ИСТИНА
                       |        ИНАЧЕ ВЫБОР
                       |                КОГДА Номенклатура.Габарит1 <= РазмерыРучнойКлади.Габарит1
                       |                        И Номенклатура.Габарит2 <= РазмерыРучнойКлади.Габарит2
                       |                        И Номенклатура.Габарит3 <= РазмерыРучнойКлади.Габарит3
                       |                    ТОГДА ИСТИНА
                       |                ИНАЧЕ ЛОЖЬ
                       |            КОНЕЦ
                       |    КОНЕЦ КАК Габариты,
                       |    ВЫБОР
                       |        КОГДА РазмерыРучнойКлади.СуммаГабаритов = 0
                       |            ТОГДА ИСТИНА
                       |        ИНАЧЕ ВЫБОР
                       |                КОГДА Номенклатура.Габарит1 + Номенклатура.Габарит2 + Номенклатура.Габарит3 <= РазмерыРучнойКлади.СуммаГабаритов
                       |                    ТОГДА ИСТИНА
                       |                ИНАЧЕ ЛОЖЬ
                       |            КОНЕЦ
                       |    КОНЕЦ КАК СуммаГабаритов
                       |ПОМЕСТИТЬ ВТГабариты
                       |ИЗ
                       |    Справочник.Номенклатура КАК Номенклатура,
                       |    РегистрСведений.РазмерыРучнойКлади КАК РазмерыРучнойКлади
                       |ГДЕ
                       |    Номенклатура.КатегорияТовара.ПроверятьРазмерыРучнойКлади = ИСТИНА
                       |    И Номенклатура.ФлагИнтерМаг = 1
                       |;
                       |
                       |////////////////////////////////////////////////////////////////////////////////
                       |ВЫБРАТЬ
                       |    ВТГабариты.ШтрихКод КАК ШтрихКод,
                       |    ВТГабариты.КодАвиакомпании
                       |ИЗ
                       |    ВТГабариты КАК ВТГабариты
                       |ГДЕ
                       |    (ВТГабариты.ГабаритыЗаполнены = ИСТИНА)
                       |    И (ВТГабариты.Габариты
                       |            И ВТГабариты.СуммаГабаритов = ИСТИНА)
                       |
                       |УПОРЯДОЧИТЬ ПО
                       |    ШтрихКод
                       |АВТОУПОРЯДОЧИВАНИЕ";
        РезультатЗапроса = Запрос.Выполнить();

Запрос1 - 50%
Запрос2 - 18%

А ведь запросы вроде одинаковые. Точнее нет! Второй вообще с усдовием по временной таблице. Почему же так производиетльность возростает у вторго?
1 AllJoke
 
29.10.13
11:20
К чему это все я здесь написал. Первый запрос делал не я. Там из него идёт выборка такого вот содержания:

Пока ВыборкаЛимитыРучнойКлади.Следующий() Цикл
            Если НЕ ВыборкаЛимитыРучнойКлади.ГабаритыЗаполнены Тогда
                Продолжить;
            КонецЕсли;
            Если НЕ (ВыборкаЛимитыРучнойКлади.Габариты И ВыборкаЛимитыРучнойКлади.СуммаГабаритов) Тогда
                Продолжить;
            КонецЕсли;
            эл = эл + 1;
        КонецЦикла;


Ну я и решил проверку этих условий кинуть в запрос.

Причем количество элементов (в моем случае "эл") - одинаково.
2 Maxus43
 
29.10.13
11:20
|ИЗ
        |    Справочник.Номенклатура КАК Номенклатура,
        |    РегистрСведений.РазмерыРучнойКлади КАК РазмерыРучнойКлади

кроссджойн зачем? представляешь итоговую выборку? жесть какая
3 AllJoke
 
29.10.13
11:23
(2) см (1) - не я писал. Я только временную таблицу создал, чтобы условия выбирать.
4 Maxus43
 
29.10.13
11:24
и смотри не % времени, а время выполнения.
И не забывай про кэширование, чтобы замерить правильно - надо несколько раз выполнить запрос последовательно, и взять общий показатель времени
5 AllJoke
 
29.10.13
11:27
да я уже и так и так процедуру выполнял. У меня эти два запроса на разных кнопках висят. Перезапустил 1С, выполняю Запрос2 потом Запрос1 - время одинаковое. Затем выполняю Запрос2, Запрос1 снова - второй быстрее в два раза. Выполняю Запрос1, Запрос2 - все равно второй быстрее. Причем, хочу заметить, что после первого запросы идёт ещё и перебор элементов по условиям. Эти условия я и воткнул в Запрос2
6 Sabbath
 
29.10.13
11:30
(5) Все волшебство в кэше имхо. Второй раз запрос может выполнятсья намного быстрее. Перезапусти и проверь еще раз. Первый раз будет дольше.
7 Maxus43
 
29.10.13
11:32
SQL?
dbcc freeproccache
выполняй запрос 1
dbcc freeproccache
выполняй запрос 2
8 H A D G E H O G s
 
29.10.13
11:33
Оба запроса - херня.
9 Maxus43
 
29.10.13
11:34
(8) ты не умничай, а проставляйся давай
10 Sabbath
 
29.10.13
11:34
(8) вопрос не в этом, а почему вторая херня быстрее)
11 AllJoke
 
29.10.13
11:36
(10) вот.
12 H A D G E H O G s
 
29.10.13
11:36
(9) Рано есчо.
13 AllJoke
 
29.10.13
11:36
и я о том же.
14 AllJoke
 
29.10.13
11:37
(8) обоснуй, что оба запроса херня. Кстатип, я скорей того же мнения, просто ещё раз говорю - запрос НЕ мой. Оптимизирую вот чужой код.
15 Maxus43
 
29.10.13
11:38
(11)>(7)
Потом дальше уж, надо достоверные данные, точнее - первое выполнение запроса 2
16 hhhh
 
29.10.13
11:39
(14) желательно еще с перезагрузкой компа, чтобы все кеши удалились. Перезагружаешь комп, выполняешь Запрос1, потом перезагружаешь комп, выполняешь запрос2. Потом результаты сюда выкладываешь.

кеш - это такая штука: в 10 раз может время отличаться, причем на одном и том же запросе.
17 H A D G E H O G s
 
29.10.13
11:44
(14) "обоснуй, что оба запроса херня."

Ты мне не доверяешь?
18 Sabbath
 
29.10.13
11:44
(16) может и в 20, у меня было, думал я гений-оптимизатор, оказалось все прозаичнее))