![]() |
|
v7: После перевода базы на SQL время выполнения запроса возросло в 50 раз! | ☑ | ||
---|---|---|---|---|
0
Калиостро
28.05.13
✎
00:10
|
Справочник номенклатуры содержит около 25000 элементов.
Количество уровней - 6. Есть реквизит "Код сортировки", строка, длина 3. Используется для групп и элементов. Фактически заполняется только для групп с целью отсортировать для вывода прайс-листа и каталога. СписокНоменклатуры - заполняется элементами с учетом нескольких фильтров и содержит около 5000 элементов И дальше запрос. ТекстЗапроса = " |Обрабатывать НеПомеченныеНаУдаление; |Номенклатура = Справочник.Номенклатура.ТекущийЭлемент; |Условие (Номенклатура в СписокНоменклатуры); |Группировка Номенклатура Упорядочить по Номенклатура.КодСортировки,Номенклатура.Наименование;"; На базе DBF выполнялся 20 сек. Теперь, после перевода на SQL, время выполнения запроса около 18 мин! |
|||
1
Калиостро
28.05.13
✎
00:11
|
Если делаю прямой запрос
|select | СпрНоменклатура.ID [Номенклатура $Справочник.Номенклатура] |,$СпрНоменклатура.КодСортировки As КодСортировки |,РОД1.ID [Родитель1 $Справочник.Номенклатура] |,РОД2.ID [Родитель2 $Справочник.Номенклатура] |,РОД3.ID [Родитель3 $Справочник.Номенклатура] |,РОД4.ID [Родитель4 $Справочник.Номенклатура] |,РОД5.ID [Родитель5 $Справочник.Номенклатура] |,РОД6.ID [Родитель6 $Справочник.Номенклатура] |from | $Справочник.Номенклатура AS СпрНоменклатура |LEFT JOIN | $Справочник.Номенклатура РОД1 ON СпрНоменклатура.parentID = РОД1.ID |LEFT JOIN | $Справочник.Номенклатура РОД2 ON РОД1.parentID = РОД2.ID |LEFT JOIN | $Справочник.Номенклатура РОД3 ON РОД2.parentID = РОД3.ID |LEFT JOIN | $Справочник.Номенклатура РОД4 ON РОД3.parentID = РОД4.ID |LEFT JOIN | $Справочник.Номенклатура РОД5 ON РОД4.parentID = РОД5.ID |LEFT JOIN | $Справочник.Номенклатура РОД6 ON РОД5.parentID = РОД6.ID |WHERE | СпрНоменклатура.ID IN (SELECT Val FROM #СписокНоменклатуры) |ORDER BY | $СпрНоменклатура.КодСортировки |"; То на выходе необходимый список элементов со всеми группами. Но как вытащить ту же структуру групп с сортировкой по полю "КодСортировки", что получается в результате черного запроса? |
|||
2
Злопчинский
28.05.13
✎
00:17
|
"КодСортировки" - стоит флажок сортировка" в пофигуртаоре?
|
|||
3
Калиостро
28.05.13
✎
00:25
|
(2) Нет.
|
|||
4
Злопчинский
28.05.13
✎
00:29
|
(3) а попробовать поставить?
|
|||
5
Злопчинский
28.05.13
✎
00:31
|
и не нравится мне
|Условие (Номенклатура в СписокНоменклатуры); с учетом 25000 раз проверить вхождение в список из 5000 элементов... |
|||
6
Злопчинский
28.05.13
✎
00:32
|
для начала тупо закомментируй это условие и проверь.
|
|||
7
Калиостро
28.05.13
✎
00:34
|
(4), (5) спасибо, завтра буду экспериментировать, отпишусь.
|
|||
8
Холст
28.05.13
✎
01:01
|
(5) а оно не кешируется разве ?
|
|||
9
Злопчинский
28.05.13
✎
01:01
|
(8) хз, я не спец. но мну такое не нравится...
|
|||
10
Холст
28.05.13
✎
01:04
|
(9) а чем ты заменяешь подобное условие ?
|
|||
11
Злопчинский
28.05.13
✎
01:07
|
(10) ничем, ятакой хренью не занимаюсь, у меня номенклатуры на порядок меньше.. ;-)
. если это разовый отчет - то и пофиг. если это регулярный отчет - то в эти 5000 прописать флажок=1 в индексируемое поле и отбирать по этому полю. . но я по запросам и их тонкой трактовке - не спец. лучше спецов дождаться. |
|||
12
viktor_vv
28.05.13
✎
01:56
|
Можно еще попробовать для штатного черного
Запрос.ВключитьSQL(0) ; Запрос.Выполнить(ТекстЗапроса); |
|||
13
Balabass
28.05.13
✎
02:09
|
(12) +1
|
|||
14
второй Вах
28.05.13
✎
02:36
|
ни разу не встречал чтоб под скуль сервером быстее чем на дбф работало
|
|||
15
второй Вах
28.05.13
✎
02:45
|
+ в таких мелких базах, разумеется
|
|||
16
МихаилМ
28.05.13
✎
09:30
|
в 1с77 sql чтобы это запрос работал быстрее,
нужно отказаться от сортировки. тк для каждого элемента выборки после получения выборки будет сгенерирован запрос 5000 элементов = + 5000 запросов. поэтому лучше сортировать тз после выборки и выгрузки также очень медленно реализована передача списка отбора оператора В : для каждого элемента создается временная хранимая процедура, выполняется затем уничтожается. конструкцию в лучше заменть Условие (Номенклатура = пар[1] ИЛИ ... Номенклатура = пар[N]. есть ограничение на размер текста запроса odbc клиента так что в одном запросе можно указать не более 2200 9 символьных ключей. |
|||
17
пипец
28.05.13
✎
09:31
|
в скуле упорядочивать по текстовому полю типа наименование - да еще вторым номером ...
|
|||
18
Sorm
28.05.13
✎
09:43
|
(0) "@Условие (Номенклатура в СписокНоменклатуры)" убрать. По возможности заменить джоином с временной таблицей(плохо знаю запросы 1с 7.7). Отребилдить индексы на таблице номенклатуры.
|
|||
19
МихаилМ
28.05.13
✎
09:48
|
(2)
почему в запросе нет подсказок "nolock" лучше элементы выбирать отдельно , группы отдельно (есть индекс для групп) |
|||
20
7Hawk7
28.05.13
✎
10:31
|
ВыбратьЭлементы() в 7 для справочников работает быстрее запроса, попробуй выборку.
|
|||
21
Калиостро
28.05.13
✎
10:37
|
(11) Отчет не разовый, запускается как минимум 1 раз в день по регламенту или по требованию.
Флаг сортировки у реквизита "КодСортировки" поставил. Команду ВключитьSQL(1) добавил. Результат практически нулевой. (19) nolock в запросе поставлю. Запрос в (1) запускался в тестовой базе. (20) ОК, буду пробовать. |
|||
22
viktor_vv
28.05.13
✎
10:48
|
(21) Надо ВключитьSQL(0) .
|
|||
23
viktor_vv
28.05.13
✎
10:49
|
(22)+ Не факт что поможет, но бывает.
|
|||
24
МихаилМ
28.05.13
✎
11:29
|
(20) выбрать элементы быстрее работает для dbf варианта
для sql выборка из запросов быстрее |
|||
25
7Hawk7
28.05.13
✎
11:53
|
(24) проводил замеры? я да, и результат указал в (20)
|
|||
26
МихаилМ
28.05.13
✎
12:00
|
(25)
конечно мерил. в 2003 году. естественно файловая база и ms sql были доступны через сеть 100 mb локальные замеры - бессмысленны. |
|||
27
dk
28.05.13
✎
12:13
|
проверял несколько раз на разных базах скуль
если в списке значений для фильтра больше 100 элементов, то быстрее на клиенте отфильтровать, через Условие (СписокНоменклатуры.Принадлежит(Номенклатура)=1) |
|||
28
ЧеловекДуши
28.05.13
✎
12:18
|
(0) Это нормальное явление, 1С не оптимизирует запросы к SQL, поэтому и тормоза.
Начни осваивать 1С++ и прямые запросы :) |
|||
29
ЧеловекДуши
28.05.13
✎
12:18
|
(20) Бред, нет нечего лучше, чем наш Select From $Справочник.Такой-то :)
|
|||
30
ДенисЧ
28.05.13
✎
12:19
|
(29) Есть... TRUNCATE TABLE $Справочник.Такойто...
|
|||
31
ЧеловекДуши
28.05.13
✎
12:20
|
(1) >>> |LEFT JOIN
| $Справочник.Номенклатура РОД1 ON СпрНоменклатура.parentID = РОД1.ID |LEFT JOIN | $Справочник.Номенклатура РОД2 ON РОД1.parentID = РОД2.ID |LEFT JOIN | $Справочник.Номенклатура РОД3 ON РОД2.parentID = РОД3.ID |LEFT JOIN | $Справочник.Номенклатура РОД4 ON РОД3.parentID = РОД4.ID |LEFT JOIN | $Справочник.Номенклатура РОД5 ON РОД4.parentID = РОД5.ID |LEFT JOIN | $Справочник.Номенклатура РОД6 ON РОД5.parentID = РОД6.ID Убери эту гадость :) |
|||
32
ЧеловекДуши
28.05.13
✎
12:20
|
(30) Злодей ;)
|
|||
33
Злопчинский
28.05.13
✎
13:04
|
ну так что?
|
|||
34
sapphire
28.05.13
✎
13:05
|
(30) Я тебя заразил? :)
|
|||
35
sapphire
28.05.13
✎
13:06
|
(0) Версия SQL?
|
|||
36
Калиостро
28.05.13
✎
13:10
|
(35) 2000
|
|||
37
Калиостро
28.05.13
✎
13:11
|
Такой запрос
|Обрабатывать НеПомеченныеНаУдаление; |Номенклатура = Справочник.Номенклатура.ТекущийЭлемент; |Группировка Номенклатура Упорядочить по Номенклатура.КодСортировки;"; Без фильтров и без сортировки по наименованию отрабатыаает на локальной машине за 7 сек, на сервере - 15 сек. |
|||
38
dk
28.05.13
✎
13:15
|
(37) добавь "без итогов"
|
|||
39
dk
28.05.13
✎
13:18
|
(38)+ сделай по 2-3 запуска и посмотри как меняется / не меняется время
|
|||
40
Эмбеддер
28.05.13
✎
13:20
|
а если вместо СпрНоменклатура.ID [Номенклатура $Справочник.Номенклатура]
сделать просто СпрНоменклатура.ID ? |
|||
41
Калиостро
28.05.13
✎
13:52
|
+(37) К запросу добавляю
|Условие (Номенклатура в СписокНоменклатуры); СписокНоменклатуры содержит 12000 элементов. На ноутбуке (тоже SQL 2000) запрос выполняется 10 минут. На сервере не проверял. Все равно долго. |
|||
42
Калиостро
28.05.13
✎
13:57
|
(40) У меня не получается прямым запросом вытащить иерархию групп для СписокНоменклатуры, упорядоченную по КодСортировки. Если есть образец, буду премного благодарен.
Поэтому сейчас пытаюсь выйти на приемлемое время с помощью черного запроса. Пусть не 20 сек, как в DBF, но и не 10 минут же! |
|||
43
Злопчинский
28.05.13
✎
14:03
|
мне принципиально кажется что необходимость регулярно проверять условие по вхождение в немелкий список - что-то в концепции попраить надо...?
|
|||
44
Serginio1
28.05.13
✎
14:09
|
(1) Посмотри http://1c.proclub.ru/modules/mydownloads/personal.php?cid=115&lid=2019 там есть обработка вывода иерархии
добавил обработки по группировке данных и выводе с учетом иерархии и суммам по группам иерархи из ТаблицыЗначений |
|||
45
Эмбеддер
28.05.13
✎
14:09
|
(42) и все-таки еще раз - тормоза могут быть уже при чтении результата запроса. попробуй убрать [..$Справочник], считай просто строки
|
|||
46
dk
28.05.13
✎
14:10
|
(42) попробуй вариант (27)
|
|||
47
Эстет хренов
28.05.13
✎
14:35
|
дурная работа, уже давно бы сделал справочник Прайс-лист в котором бы настраивал всю специфику каталогов и прайс-листов.
Там можно создать различную иерархию, множественную вложенность товаров, свою сортировку, свое представление и оформление итд итп. |
|||
48
Калиостро
28.05.13
✎
14:49
|
(46) И как там получить отсортированный иерархический список групп по списку номенклатуры?
|
|||
49
Калиостро
28.05.13
✎
14:56
|
(47) Дурная - не дурная, лучше не давать оценок, пока видишь только вершину айсберга проблем. База dbf работала с 2005 года. Чтобы после перевода на SQL запрос по номенклатуре выполнялся в 50 раз медленнее - этого, конечно, не ожидал.
|
|||
50
Злопчинский
28.05.13
✎
15:13
|
(49) ну и фигли - это не значит, что все хорошо. как правило - смотришь на все это и думаешь, блин, ну что за уродство...
. не.. когда из 25000 надо отфильтровать по вхождению в 12000 список - это не 5-6 позиций подбираемых руками - это уже какая-то система. а система - это флажки, реквизиты, но ну никак не список на 5000/12000 позиций, однозначно в консерватории... |
|||
51
Калиостро
28.05.13
✎
15:30
|
(50) Немного не в тему топика, но раз уж зашел разговор. В номенклатуре есть признак "Включать в прайс" и варианты:
1. Всегда (например, позиции собственного производства). 2. Никогда (специфические позиции раньше торговали массово, а теперь распродажа остатков с прилавка). 3. При остатке больше заданного количества (например, когда через интернет-магазин продавать меньше упаковки невыгодно). Формировать список, по-моему, здесь можно только в момент выгрузки, анализировать и перезаписывать флажки при проведении документов - еще хуже. |
|||
52
Mikeware
28.05.13
✎
15:32
|
(49) ну и у меня работает с 2005. иногда смотришь и думаешь - убил бы того, кто такое написал... а поразмыслишь - ну разве ж это повожд для самоубийства? :-)
|
|||
53
Калиостро
28.05.13
✎
15:33
|
+ (51) Я и не говорю, что там все идеально. Система дописывалась годами. Где-то были глобальные переделки, где-то костыли. Сейчас тоже надо поставить костыль. Передохнем, а дальше подумаем.
|
|||
54
Калиостро
28.05.13
✎
15:37
|
(52) + 100. Если бы каждый раз при возникновении новой задачи надо было переделывать архитектуру с нуля, так и занимались бы описанием, согласованием ТЗ, тестированием, отладкой 90% времени. Лучше сейчас решить задачу на тройку. Если критических глюков не будет, когда-нибудь в свободное время займемся рефакторингом.
|
|||
55
aka AMIGO
28.05.13
✎
15:38
|
(0) переходи на прямые © запросы :)
у меня примерно такая-же ситуация была, когда надежды шефа на ускорение разрушились: отчет в скуле стал работать в 3 раза медленнее.. всего в 3! а у тебя 50 :) |
|||
56
Калиостро
28.05.13
✎
15:43
|
(55) Дайте рыбу списать:(
Надо получить иерархию групп для СписокНоменклатуры, упорядоченную по КодСортировки. Как в черном запросе " |Номенклатура = Справочник.Номенклатура.ТекущийЭлемент; |Группировка Номенклатура Упорядочить по Номенклатура.КодСортировки; |Условие (Номенклатура в СписокНоменклатуры); |
|||
57
Sorm
28.05.13
✎
15:52
|
(1) |LEFT JOIN
|(Select Val from FROM #СписокНоменклатуры order by Val) Список |on Список.ID = СпрНоменклатура.ID Я не знаю, так можно делать в прямых запросах 7.7.... Но скорость запроса возрастет. |
|||
58
Сияющий Асинхраль
28.05.13
✎
15:54
|
(27) А еще быстрее, как ни странно, заменить
Условие (СписокНоменклатуры.Принадлежит(Номенклатура)=1) На: Условие (СписокНоменклатуры.НайтиЗначение(Номенклатура)<>0) Причем, что забавно НайтиЗначение частенько работает быстрее чем Принадлежит буквально в разы... |
|||
59
Mikeware
28.05.13
✎
15:57
|
(58) потому, что Найти - ищет в списке, а принадлежит - в иерархии. а поиск в иерархии - это запрос к базе
|
|||
60
Mikeware
28.05.13
✎
15:57
|
+(59) и он может отличаться не в разы, а на порядок
|
|||
61
Mikeware
28.05.13
✎
15:58
|
(56) все-таки, я не понял что тебе нужно _в_результате_
|
|||
62
Сияющий Асинхраль
28.05.13
✎
16:01
|
(60) Согласен... Давно на эту бадягу напоролся, уже несколько лет семеркой занимаюсь от случая к случаю, но разница на опыте оказалась такая существенная, что до сих пор помню, что Принадлежит лучше не использовать :-)))
|
|||
63
Калиостро
28.05.13
✎
16:05
|
(61)Нужен список групп в определенной последовательности. Внутри одной группы порядок по полю "КодСортировки". Нужны не все группы, а только те, в которые входят элементы из списка.
Вроде бы в запросе (56) это просматривается. |
|||
64
Эмбеддер
28.05.13
✎
16:05
|
(57) вообще-то это делается так
LEFT JOIN #СписокНоменклатуры Список on Список.ID = СпрНоменклатура.ID автор, тебя здесь все уговаривают сделай так, сделай так. а ты придумываешь всякие отмазки почему не надо это делать |
|||
65
Эмбеддер
28.05.13
✎
16:06
|
64+ потому что в принципе на SQL такие прямые запросы в принципе не могут долго выполняться
|
|||
66
Эмбеддер
28.05.13
✎
16:10
|
вместо LEFT JOIN просто JOIN - так скопировал
|
|||
67
Bugmenot
28.05.13
✎
16:13
|
(0) - и после этого вы еще считаете, что архитектура 1С - это Порше?
v8: Переход c Oracle Application на 1С |
|||
68
Mikeware
28.05.13
✎
16:14
|
(63) выбери всех прямых родителей элементов списка в индексированную таблицу, и сгруппируй по иерархии.
|
|||
69
Bugmenot
28.05.13
✎
16:15
|
(0) - это разрыв шаблона, обычно при переходе на SQL все должно убыстряться, т.к. по сети гуляют не таблицы, а запросы.
|
|||
70
Sorm
28.05.13
✎
16:17
|
(64)+ Буду знать. Ну я его код скопировал.... Идея понятна, конечно - уйти от where.
|
|||
71
Classic
28.05.13
✎
16:21
|
(69)
СКЛ в принципе зло |
|||
72
ДенисЧ
28.05.13
✎
16:23
|
(69) Не в этой жизни. То есть не в 1с
|
|||
73
Bugmenot
28.05.13
✎
16:25
|
(71) - дело не в SQL, а в том, что фирма 1Це не оптимизиорвала свою т.н. SQL версию для SQL
|
|||
74
Эмбеддер
28.05.13
✎
16:30
|
(69) все меньше остается 1Сников, которые видели 7-ку, а сама она переходит в разряд мифов
кроме того как автор выводит группировку, будет странный результат - не учитывается, что элементы будут на разных уровнях |
|||
75
Калиостро
28.05.13
✎
16:30
|
(68) Нужны не только прямые родители, а вся иерархия от 1 уровня.
|
|||
76
Mikeware
28.05.13
✎
16:32
|
(75) ты читать умеешь?
|
|||
77
Mikeware
28.05.13
✎
16:32
|
(74) а "восьмерка разжижает мозг"©
|
|||
78
ДенисЧ
28.05.13
✎
16:33
|
(77) не всем, не всем....
|
|||
79
Калиостро
28.05.13
✎
16:36
|
(76) Запрос в (1) дает все нужные группы. Попробую покрутить ИТ.
|
|||
80
Serginio1
28.05.13
✎
16:43
|
(79) Сделай дерево наподобие в 44 и будет тебе счастье.
Или Сделай на индексированной таблице с отбором по родителю |
|||
81
Калиостро
28.05.13
✎
17:06
|
(64)
ТекстЗапроса = " |SELECT | СпрНоменклатура.ID [Номенклатура $Справочник.Номенклатура] |FROM | $Справочник.Номенклатура as СпрНоменклатура (NOLOCK) |LEFT JOIN | #СписокНоменклатуры Список on Список.ID = СпрНоменклатура.ID |"; Запрос = СоздатьОбъект("ODBCRecordSet"); Запрос.Отладка(1); Запрос.УложитьСписокОбъектов(СписокНоменклатуры, "#СписокНоменклатуры", "Номенклатура"); ТЗ = Запрос.ВыполнитьИнструкцию(ТекстЗапроса); Error: State 42S22, native 207, message [Microsoft][ODBC SQL Server Driver][SQL Server]Invalid column name 'ID'. |
|||
82
ДенисЧ
28.05.13
✎
17:07
|
Список.ID
а документацию кто читать будет? |
|||
83
viktor_vv
28.05.13
✎
17:07
|
#СписокНоменклатуры Список on Список.VAL = СпрНоменклатура.ID
|
|||
84
Калиостро
28.05.13
✎
17:40
|
Пойдем путем банана...
|SELECT | СпрНоменклатура.ID [Номенклатура $Справочник.Номенклатура] |FROM | $Справочник.Номенклатура as СпрНоменклатура (NOLOCK) |JOIN | #СписокНоменклатуры Список on Список.Val = СпрНоменклатура.ID |"; Запрос = СоздатьОбъект("ODBCRecordSet"); Запрос.УложитьСписокОбъектов(СписокНоменклатуры, "#СписокНоменклатуры", "Номенклатура"); Выдает список номенклатуры из СписокНоменклатуры. Групп нет. Печаль. |
|||
85
Mikeware
28.05.13
✎
17:43
|
(84) сочувствую.
parentId, а затем (68) |
|||
86
Mikeware
28.05.13
✎
17:43
|
кстати, distinct еще...
|
|||
87
Ёпрст
гуру
28.05.13
✎
17:49
|
(0) скуль какой хоть ?
|
|||
88
Ёпрст
гуру
28.05.13
✎
17:51
|
вот, один из способов показа всей иерархии (но, для скуля>=2005)
http://www.1cpp.ru/forum/YaBB.pl?num=1367434674 |
|||
89
NS
28.05.13
✎
18:03
|
(0) Есть очень быстрый способ штатного получения всех групп... Отсортировать можно уже в ТЗ.
|
|||
90
NS
28.05.13
✎
18:05
|
А понял, тебе не группы нужно.
|
|||
91
Калиостро
28.05.13
✎
18:09
|
(89) Элементы у меня уже есть. Мне нужны как раз группы. Но не все и в определенном порядке.
|
|||
92
Калиостро
28.05.13
✎
18:09
|
(87) 2000
|
|||
93
NS
28.05.13
✎
18:10
|
(91) А что, отсортировать их после получения нельзя?
Или у тебя их миллион? |
|||
94
Serginio1
28.05.13
✎
18:15
|
(93) Ему нужна иерархия. Ему уже указали как решить проблему
Через индексированную таблицу с рекурсивным отбором по родителю, либо через построение дерева 44. |
|||
95
fisher
28.05.13
✎
18:31
|
(0) А без упорядочивания сабжевый запрос сколько выполняется?
|
|||
96
Serginio1
28.05.13
✎
18:34
|
То что Ёпрст предложил в 88 Получаешь таблицу
А дальше рекурсивно Установить Индекс Тз.ДобавитьИндекс("РодительИндех", "Родитель"); Процедура ВывестиУровень(Родитель) перем ТзРодителей; Тз.УстановитьФильтр(Родитель, Родитель, "РодительИндех"); Тз.Выгрузить(ТзРодителей); ТзРодителей.Сортировать("IsFolder,КодСортировки"); ТзРодителей.ВыбратьСтроки(); Пока ТзРодителей.ПолучитьСтроку()=1 Цикл //Вывести текущий элемент Если ТзРодителей.IsFolder=1 Тогда ВывестиУровень(Тз.Номенклатура) КонецЕсли; КонецЦикла; КонецПроцедуры |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |