Имя: Пароль:
1C
1С v8
чем заменить конструкцию подобно, ускорить запрос.
0 zladenuw
 
20.06.13
13:21
есть такой запрос

 "ВЫБРАТЬ
|    Авто.Ссылка,
|    Авто.Кузов
|ПОМЕСТИТЬ СписокФирм
|ИЗ
|    Справочник.Авто КАК Авто
|ГДЕ
|    Авто.Модель В ИЕРАРХИИ(&Модель)
|
|СГРУППИРОВАТЬ ПО
|    Авто.Ссылка,
|    Авто.Кузов
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
|    СервисныеАкции.Авто,
|    СервисныеАкции.Дата,
|    СервисныеАкции.Источник,
|    СервисныеАкции.Выполнено,
|    СервисныеАкции.ТекстСообщения,
|    СервисныеАкции.Причина,
|    СервисныеАкции.НеВыполнено,
|    СервисныеАкции.ДатаВыполнения
|ИЗ
|    РегистрСведений.СервисныеАкции КАК СервисныеАкции,
|    СписокФирм КАК СписокФирм
|ГДЕ
|    ВЫБОР
|            КОГДА СервисныеАкции.Авто ССЫЛКА Справочник.Авто
|                ТОГДА СервисныеАкции.Авто = СписокФирм.Ссылка
|            ИНАЧЕ СервисныеАкции.Авто ПОДОБНО СписокФирм.Кузов
|        КОНЕЦ"

если заменить подобно на равно, запрос выполняется за секунды 2. если подобно, очень при очень долго. как ускорить ?
1 andreymongol82
 
20.06.13
13:22
(0) "если заменить подобно на равно, запрос выполняется за секунды 2"
2 zak555
 
20.06.13
13:22
зачем тебе произведение таблиц СервисныеАкции и СписокФирм ?
3 SanGvin
 
20.06.13
13:23
Фигасе какое извращенное соединение таблиц!!!!
4 zladenuw
 
20.06.13
13:24
(2) там опятка. там список Авто :). которые есть в базе. и есть сервисные акции. где много разных авто. и при заезде авто нужно проверить или есть на него сервисная акция. по этому вин код храним строкой. если есть такой автомобиль то ссылка на авто
5 zladenuw
 
20.06.13
13:25
(3) а как правильно ?
6 AaNnDdRrEeYy
 
20.06.13
13:27
зачем тут вообще подобно?
СервисныеАкции.Авто (это ссылка) ПОДОБНО СписокФирм.Кузов (и это ссылка)

как поведет себя "подобно" если применять его к ссылкам?
7 zladenuw
 
20.06.13
13:27
(6)  СписокФирм.Кузов - строка кода
8 SanGvin
 
20.06.13
13:28
(5) через соединение
9 SanGvin
 
20.06.13
13:29
тогда зачем написал "СервисныеАкции.Авто ПОДОБНО СписокФирм.Кузов" ? Поле "Авто" - это ж ссылка
10 zladenuw
 
20.06.13
13:30
(9) не Ссылка. в (4) написал же. что если есть такой автомобиль в базе, то там ссылка. если нет то строка.
11 AaNnDdRrEeYy
 
20.06.13
13:30
у вин номеров последнии 6 цифр уникальны. от них прыгай. там можно не подобно применять а к подстроке на равно условие сделать
12 zladenuw
 
20.06.13
13:34
(11) попробую. хотя вроде нет. в каких то символах заложена модель. может по последнем найти,а вот первый ключ будет отличатся. или делать двойное условие с проверкой на равенство последних. если равно то смотрим весь код или так не взлетит ?
13 SanGvin
 
20.06.13
13:35
(10) ну в любом случае условия в соединение пиши, а не в где. И проверь, на сколько быстрее станет.

ВЫБРАТЬ
СервисныеАкции.ТвоеПоле1,
СписокФирм.ТвоеПоле2
ИЗ
   РегистрСведений.СервисныеАкции КАК СервисныеАкции
   ЛЕВОЕ СОЕДИНЕНИЕ СписокФирм КАК СписокФирм
   ПО ВЫБОР
           КОГДА СервисныеАкции.Авто ССЫЛКА Справочник.Авто
               ТОГДА СервисныеАкции.Авто = СписокФирм.Ссылка
           ИНАЧЕ СервисныеАкции.Авто ПОДОБНО СписокФирм.Кузов
       КОНЕЦ

еще идею из (11) попробуй, тоже ускорить должно процесс.
14 GANR
 
20.06.13
13:36
(0) Как угодно избавиться от этого ПОДОБНО - при таком сравнении индексы идут лесом и сканируется вся таблица (table scan), что и является тормозящей операцией в плане запроса.
15 zladenuw
 
20.06.13
13:37
(13) да так и сделал. жду вот. крутится запросы еще. все равно долго. только конструкция подобно и можно идти пить что то. в прошлый раз до 6 часов выполнялось. ужас.  может где то ограничение на самом сервере постгреса на объем запроса или это не при чем
16 zladenuw
 
20.06.13
13:38
(14) тогда проще в фоне ночью, обрабатывать этот регистр и убивать лишение символы в поле. и использовать конструкцию =
17 SanGvin
 
20.06.13
13:38
(15) значит, только через подстроку и условие на равенство
18 SanGvin
 
20.06.13
13:39
(16) а не проще "лишние символы" при вводе както контроллировать?
19 GANR
 
20.06.13
13:41
+(14) И еще, что будет если заменить ВЫБОР КОГДА в секции ГДЕ на ОБЪЕДИНИТЬ ВСЕ и 2 запроса с разными условиями соединения? Не побыстрее стало?
(16) А может можно как-то методически решить вопрос - подогнать данные таким образом, чтобы эта самая операция = стала применима или вообще перейти на сравнение по Ссылке?
20 GANR
 
20.06.13
13:43
А нельзя ли как-то уменьшить размер левой или правой таблицы? Так, хоть и без индексов, но количество сравнений будет меньше.
21 zladenuw
 
20.06.13
13:43
(19) разделить выбор. выбрать где есть ссылка и вывести и отдельно где строка и так же вывести. попробую так поигратся
22 GANR
 
20.06.13
13:43
(20) В смысле, отфильтровать данные перед операцией соединения.
23 zladenuw
 
20.06.13
13:44
(22) так есть фильтр по авто. по определенному бренду. а вот в РС неа
24 GANR
 
20.06.13
13:46
(21) Да-да... И еще при сравнении по ПОДОБНО во второй таблице ОБЪЕДИНИТЬ ВСЕ надо-бы перед проверкой этого подобно убедиться, что в проверяемых полях именно строка ТИПЗНАЧЕНИЯ(СервисныеАкции.Авто) = ТИП(Строка), иначе - не проверять.
25 GANR
 
20.06.13
13:47
(24) хотя бы урежет количество проверок по ПОДОБНО
26 zladenuw
 
20.06.13
14:00
(25) а разве такое условие это не проверяет
ВЫБОР
   КОГДА СервисныеАкции.Авто ССЫЛКА Справочник.Авто
       ТОГДА СервисныеАкции.Авто = СписокФирм.Ссылка
   ИНАЧЕ СервисныеАкции.Авто = СписокФирм.Кузов
КОНЕЦ
27 zladenuw
 
20.06.13
14:16
и самое интересное то что если условие то быстрее 1668, а соединение 1751. хотя ведь соединение должно быть быстрее
28 zladenuw
 
20.06.13
14:19
ура.
нашел как обмануть.
так выполняет 0.94

ВЫБРАТЬ
   Авто.Ссылка,
   Авто.Кузов
ПОМЕСТИТЬ СписокАвто
ИЗ
   Справочник.Авто КАК Авто
ГДЕ
   Авто.Модель В ИЕРАРХИИ(&Модель)

СГРУППИРОВАТЬ ПО
   Авто.Ссылка,
   Авто.Кузов
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   СервисныеАкции.Авто,
   СервисныеАкции.Дата,
   СервисныеАкции.Источник,
   СервисныеАкции.Выполнено,
   СервисныеАкции.ТекстСообщения,
   СервисныеАкции.Причина,
   СервисныеАкции.НеВыполнено,
   СервисныеАкции.ДатаВыполнения
ИЗ
   СписокАвто КАК СписокФирм
       ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.СервисныеАкции КАК СервисныеАкции
       ПО СписокФирм.Ссылка = СервисныеАкции.Авто
ГДЕ
   СервисныеАкции.Авто ССЫЛКА Справочник.Авто

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
   СервисныеАкции.Авто,
   СервисныеАкции.Дата,
   СервисныеАкции.Источник,
   СервисныеАкции.Выполнено,
   СервисныеАкции.ТекстСообщения,
   СервисныеАкции.Причина,
   СервисныеАкции.НеВыполнено,
   СервисныеАкции.ДатаВыполнения
ИЗ
   РегистрСведений.СервисныеАкции КАК СервисныеАкции
       ВНУТРЕННЕЕ СОЕДИНЕНИЕ СписокАвто КАК СписокАвто
       ПО СервисныеАкции.Авто = СписокАвто.Кузов
ГДЕ
   НЕ СервисныеАкции.Авто ССЫЛКА Справочник.Авто
29 zladenuw
 
20.06.13
14:26
(28) соврал по времени 0.094 :). а вот подобно все равно долго :(.
30 zladenuw
 
20.06.13
14:40
такой вопрос. сначала будет выполнена конструкция где или сначала соединение и потом где ?
31 zladenuw
 
20.06.13
15:15
можно идти отдыхать.
литает запрос. с условием и конструкцией подобно по автомобилям до 1 секунды, без условия 3 секунды.

ВЫБРАТЬ
   Авто.Ссылка,
   Авто.Кузов
ПОМЕСТИТЬ СписокАвто
ИЗ
   Справочник.Авто КАК Авто

СГРУППИРОВАТЬ ПО
   Авто.Ссылка,
   Авто.Кузов
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   СписокАкций.Авто,
   СписокАкций.Дата,
   СписокАкций.Источник,
   СписокАкций.Выполнено,
   СписокАкций.ТекстСообщения,
   СписокАкций.Причина,
   СписокАкций.НеВыполнено,
   СписокАкций.ДатаВыполнения
ИЗ
   СписокАвто КАК СписокАвто
       ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
           СервисныеАкции.Авто КАК Авто,
           СервисныеАкции.Дата КАК Дата,
           СервисныеАкции.Источник КАК Источник,
           СервисныеАкции.Выполнено КАК Выполнено,
           СервисныеАкции.ТекстСообщения КАК ТекстСообщения,
           СервисныеАкции.Причина КАК Причина,
           СервисныеАкции.НеВыполнено КАК НеВыполнено,
           СервисныеАкции.ДатаВыполнения КАК ДатаВыполнения
       ИЗ
           РегистрСведений.СервисныеАкции КАК СервисныеАкции
       ГДЕ
           СервисныеАкции.Авто ССЫЛКА Справочник.Авто
           И НЕ СервисныеАкции.Выполнено) КАК СписокАкций
       ПО СписокАвто.Ссылка = СписокАкций.Авто

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
   СписокАкций.Авто,
   СписокАкций.Дата,
   СписокАкций.Источник,
   СписокАкций.Выполнено,
   СписокАкций.ТекстСообщения,
   СписокАкций.Причина,
   СписокАкций.НеВыполнено,
   СписокАкций.ДатаВыполнения
ИЗ
   (ВЫБРАТЬ
       СервисныеАкции.Авто КАК Авто,
       СервисныеАкции.Дата КАК Дата,
       СервисныеАкции.Источник КАК Источник,
       СервисныеАкции.Выполнено КАК Выполнено,
       СервисныеАкции.ТекстСообщения КАК ТекстСообщения,
       СервисныеАкции.Причина КАК Причина,
       СервисныеАкции.НеВыполнено КАК НеВыполнено,
       СервисныеАкции.ДатаВыполнения КАК ДатаВыполнения
   ИЗ
       РегистрСведений.СервисныеАкции КАК СервисныеАкции
   ГДЕ
       СервисныеАкции.Авто ССЫЛКА Справочник.Авто
       И НЕ СервисныеАкции.Выполнено) КАК СписокАкций
       ВНУТРЕННЕЕ СОЕДИНЕНИЕ СписокАвто КАК СписокАвто
       ПО (СписокАкций.Авто ПОДОБНО СписокАвто.Кузов)

Но есть вопрос к знатокам запросов. почему так работает быстрее, если использовать вложенные запросы ?  чем можно увидеть какой запрос уходить на сервер субд ?
32 GANR
 
21.06.13
10:26
(0) А попробуй посмотреть на план запроса, предварительно выловив его в MS SQL Profiler и заменив параметры в запросе прямыми указаниями значений. Вообще, имхо, надо попросту перепроектировать структуру данных так, чтобы не было надобности в этих часто использующихся ПОДОБНО - эта операция без какого-то специализированного индекса полнотекстового поиска полюбому приведет к полному сканированию всей таблицы, да еще в цикле, если это соединение.
33 GANR
 
21.06.13
11:10
34 GANR
 
21.06.13
11:10
35 GANR
 
21.06.13
11:12
Выдержка из (33)

Избегать конструкции ПОДОБНО (LIKE)
При работе с отборами удобно выполнять поиск контрагента не по наименованию, а путем установки отбора по условию «Содержит» по полю «Наименование». Однако это отрицательно сказывается на производительности из-за невозможности использования индексов и так приводит к запросам:

ВЫБРАТЬ .. ИЗ Справочник.Контрагенты
ГДЕ Наименование ПОДОБНО «%СтрокаПоиска%»

В таком запросе будет выполнен полный перебор всех записей таблицы. Это отрицательно сказывается на производительности.

П р и м е ч а н и е.  В последних версиях MS SQL Server LIKE стал уметь в некоторых случаях использовать поиск, но это все равно не лучший оператор.


Так что, возможно MS SQL 2008 - 2013 спасут ситуацию без реструктуризаций данных.