|
v7: Ошибка при выполнении прямого запроса | ☑ | ||
---|---|---|---|---|
0
PRO100 NigGaZ
08.10.13
✎
13:20
|
Выполняю подобный запрос
SELECT Sum(Остаток), Sum(Резерв) FROM ( SELECT Sum(Рег1.КоличествоОстаток) Остаток, (Null) Резерв FROM $РегистрОстатки.ОстаткиТМЦ(,, (Номенклатура = :ВыбНом),,) AS Рег1 UNION ALL SELECT (Null) Остаток, Sum(Рег2.КоличествоОстаток) Резерв FROM $РегистрОстатки.РезервыТМЦ(,, (Номенклатура = :ВыбНом),,) AS Рег2) AS Подзапрос Выполняю скалярный (получаю резерв и остаток), после первого выполнения пишет ошибку "Подключение занято до получения другого hstmt" интересует причина данной ошибки до этого запроса выполняю 2 запроса (приведенный выше только отдельно остаток и резерв) |
|||
1
PRO100 NigGaZ
08.10.13
✎
13:34
|
Выяснил что ошибка возникает при выполнении следующего запроса после этого
текст запроса с ошибкой SELECT Sum(Рег.КоличествоОстаток) Остаток, (Null) Резерв FROM $РегистрОстатки.ОстаткиТМЦ(,, (Номенклатура = :ВыбНом) AND (Склад = :ВыбСклад),,) AS Рег если убрать запрос (0) то все выполняется нормально.. |
|||
2
Mikeware
08.10.13
✎
13:37
|
||||
3
PRO100 NigGaZ
08.10.13
✎
13:41
|
писал
SET NOCOUNT ON может проблема в Рез = рс10.ВыполнитьСкалярный(); Сообщить(Рез.Остаток); Сообщить(Рез.Резерв); Рез = ""; ? или как закрыть курсор? |
|||
4
PRO100 NigGaZ
08.10.13
✎
14:19
|
и если убрать тестовый код то все норм... |
|||
5
Mikeware
08.10.13
✎
14:24
|
жуть. анахрена?
|
|||
6
PRO100 NigGaZ
08.10.13
✎
14:27
|
модуль проведения заявки покупателя, у меня итоговый результат 4-10 раз ускорение проведения документа на моей машине, на сервере (где sql сервер отдельно стоит) почти не дает результата около 40% прирост... поэтому пытаюсь уменьшить количество обращений к серверу...
|
|||
7
mikecool
08.10.13
✎
14:28
|
объединить в один запрос религия не позволила?
и писать (null) вместо 0 для числовых полей - я бы по рукам надавал |
|||
8
PRO100 NigGaZ
08.10.13
✎
14:29
|
(7) я исправил уже... объединить в в один где именно?
|
|||
9
PRO100 NigGaZ
08.10.13
✎
14:29
|
исправление в (4)
|
|||
10
PRO100 NigGaZ
08.10.13
✎
14:33
|
(7) просто примеры выше нереальные были писал как бы для примера, в (4) реальный код...
|
|||
11
Salimbek
08.10.13
✎
14:36
|
(9) У тебя первым выполняется ЗапросТекст, туда и вставь "SET NOCOUNT ON" Или вообще, самой первой строкой "рс.выполнитьскалярный("SET NOCOUNT ON")"... Хотя... Вот зачем тебе так много "рс4, рс6, рс10"? И возможно в одном РекордСете ты отключаешь вывод количества обработанных строк, а в другом каком-то остается включенным и продолжает падать.
|
|||
12
PRO100 NigGaZ
08.10.13
✎
14:42
|
(11) добавил во все запросы "SET NOCOUNT ON", не помогло :(
а много для того чтобы получить все нужные данные
и все запросы с параметрами и выполняются скалярно, кроме первых трех, они возвращают таблицы и только 1 раз |
|||
13
ADirks
08.10.13
✎
14:44
|
(12) подсказываю
Warning: Null value is eliminated by an aggregate or other SET operation |
|||
14
ADirks
08.10.13
✎
14:44
|
... в студии свой запрос выполни, прежде чем репу чесать
|
|||
15
mikecool
08.10.13
✎
14:47
|
(8) написать типа
селект фром (свернутая табличная часть документа) левое соединение остатки по номенклатура, склад из шапки и т.п. левое соединение резервы по номенклатура, склад из шапки и т.п. остальное если надо |
|||
16
mikecool
08.10.13
✎
14:47
|
(12) афигеть
|
|||
17
PRO100 NigGaZ
08.10.13
✎
14:52
|
(12) ну да, дело в том что не всегда нужно использовать все данные... совместно используются только остатки и резервы...
одни запросы на случай корректировки заказа, другие на случай заказа на поставку, одни на случай неподтвержденной заявки, один на случай резерва, я не знаю будет ли оптимально вернуть все в одной талице когда это не надо для обработки проведения |
|||
18
PRO100 NigGaZ
08.10.13
✎
15:02
|
(13) на запросе в (4) не пишет предупреждений, там я null не использую, и нет никаких сообщений...
ошибка так и остается :( |
|||
19
Salimbek
08.10.13
✎
15:10
|
(17) Я не знаю, как поведут себя разные РекордСеты, т.к. 1. подключены они к одной базе, 2. 1С-ка выполняет запросы все равно по порядку, смысла в том, чтобы прыгать от одного рекордсета к другому я по этому не вижу. 3. Есть шанс, что
Я бы сделал тупенько, один РС, и далее по порядку - надо такие-то данные - запрос сделал, выполнил, обработал. Надо еще что-то, следующий запрос, и т.д. Ну и последнее, как правильно озвучил (15) - какой смысл раскидывать куче маленьких запросов, если можно одним запросом вытащить все данные для работы в ТЗ, а потом уже спокойно перебирать, не бегая к БД за каждым чихом. |
|||
20
PRO100 NigGaZ
08.10.13
✎
15:15
|
(19) с рс4 по рс 7 я и собирался в 1 запрос собрать
|
|||
21
PRO100 NigGaZ
08.10.13
✎
15:18
|
что будет быстрее списк номенклатуры Left Join с регистрами или в каждом регистре select val from #СписокНом?
|
|||
22
trad
08.10.13
✎
15:23
|
Ставлю на то, что из-за null или еще чего то, прет warning, который 1с++ный рекордсет не выгребает (так устроен этот рекордсет) из буфера. Следовательно обращения к базе недопустимы пока буфер занят.
Нужно либо избавится от варнинга, либо ODBCRecordSet::Закрыть(), но тогда, вроде, prepare отвалится. |
|||
23
trad
08.10.13
✎
15:24
|
* из-за null в агрегатной функции
|
|||
24
PRO100 NigGaZ
08.10.13
✎
16:08
|
Так же будет лучше всего?
|
|||
25
trad
08.10.13
✎
16:21
|
Если в ИБ практикуется массовое перепроведение документов, то
УложитьСписокОбъектов(СписокНоменклатуры, "#СписНом") при проведение лучше не пользоваться. Чревато http://support.microsoft.com/?scid=kb;en-us;891553&spid=2852 |
|||
26
trad
08.10.13
✎
16:21
|
+ равно как и любыми фильтрами на основе tempdb
|
|||
27
PRO100 NigGaZ
08.10.13
✎
16:22
|
Тогда так?
|
|||
28
mikecool
08.10.13
✎
16:23
|
табличную часть дока закинуть во времянку и юзать ее далее
можно даже пробовать одним пакетом это выполнить |
|||
29
mikecool
08.10.13
✎
16:24
|
+28 если будут лефт джойны вирт. таблиц - то им в обязаловку устраивать ограничения на номенклатуру и склады
|
|||
30
PRO100 NigGaZ
08.10.13
✎
16:25
|
такой массив не пойдет? (' U ',' V ',' 6 ',' K ',' N ',' R ',' S ',' T ',' O ',' L ',' I ',' H ',' M ',' P ')
|
|||
31
trad
08.10.13
✎
16:27
|
(27) Нужного списка номенклатуры разве нет на сервере? Заказ твой не имеет ТЧ например с номенклатурой этой?
|
|||
32
PRO100 NigGaZ
08.10.13
✎
16:27
|
имеет
|
|||
33
trad
08.10.13
✎
16:28
|
ну так и возьми этот список оттуда
|
|||
34
PRO100 NigGaZ
08.10.13
✎
16:29
|
а понял
|
|||
35
trad
08.10.13
✎
16:30
|
угу
судя по [Номенклатура $Справочник.Номенклатура] сомневаюсь что понял |
|||
36
PRO100 NigGaZ
08.10.13
✎
16:32
|
я же буду потом выгружать в ТЗ результат и как поиск по таблице будет проходить если там значения будут вида ' I '?
|
|||
37
trad
08.10.13
✎
16:35
|
какой такой поиск по ТЗ?
мы же про замену #СписНом на то, что в ТЧ записанной в БД |
|||
38
Mikeware
08.10.13
✎
16:36
|
(25) ну ReconnectNative не зря придуман :-)
|
|||
39
trad
08.10.13
✎
16:36
|
(38) метод для лентяев - не наш метод :-)
|
|||
40
PRO100 NigGaZ
08.10.13
✎
16:37
|
|
|||
41
PRO100 NigGaZ
08.10.13
✎
16:37
|
+(40) и потом работать с этой ТЗ
|
|||
42
Z1
08.10.13
✎
16:39
|
(25) в sql2005 исправили
|
|||
43
trad
08.10.13
✎
16:41
|
(42)Да, но у автора 2000 раз не указано иного
|
|||
44
trad
08.10.13
✎
16:42
|
(40)верно
|
|||
45
trad
08.10.13
✎
16:44
|
(40)
можно и по одной ВТ на регистр оставить. Развернуть по фирмам. Сгруппировать по товарам, а "УсловиеПоФирмам" применить при агрегировании. Еще не забыть подумать про дубли строк. |
|||
46
trad
08.10.13
✎
16:45
|
* про дубли строк в ТЧ
|
|||
47
Z1
08.10.13
✎
16:47
|
(0) а ты можешь сформулировать свою исходную задачу ???
|
|||
48
PRO100 NigGaZ
08.10.13
✎
16:50
|
(47) Цитирую "Сделать быстро когда проводится заявка покупателя"
(45) Попробую так не делал еще... (43) да 2000 sp4 |
|||
49
PRO100 NigGaZ
08.10.13
✎
16:54
|
(48) нет не понял что надо делать
|
|||
50
PRO100 NigGaZ
08.10.13
✎
17:14
|
(45) Развернуть по фирмам
в ВТ (Номенклатура, Фирма) "УсловиеПоФирмам" применить при агрегировании это я так понимаю когда пишем SUM(Рег1.КоличествоОстаток ОстатокПоСкладу) и как тут? :( |
|||
51
trad
08.10.13
✎
17:19
|
sum(case when /*УсловиеПоФирмам*/ then Рег1.КоличествоОстаток else 0 end) ОстатокПоФирме,
sum(Рег1.КоличествоОстаток) ОстатокПоСкладу, |
|||
52
trad
08.10.13
✎
17:21
|
* ну или около того, просто текст как то тяжело у тебя читается
|
|||
53
PRO100 NigGaZ
08.10.13
✎
17:25
|
(51) даааааа
Спасибо :) это очень полезно, я CASE внутри агрегирования еще не использовал все получилось :) |
|||
54
Ёпрст
08.10.13
✎
17:30
|
но лучше кейс не юзать
|
|||
55
PRO100 NigGaZ
08.10.13
✎
17:34
|
почему?
|
|||
56
Ёпрст
08.10.13
✎
17:36
|
(55) медленно
|
|||
57
PRO100 NigGaZ
08.10.13
✎
17:39
|
(56) медленнее чем брать 2 таблицы регистров дважды? О_о
|
|||
58
Z1
08.10.13
✎
17:40
|
(56) не факт.
case в клаузе select ничего не стоит case во where скорее всего приведет к скану таблицы |
|||
59
PRO100 NigGaZ
08.10.13
✎
17:45
|
(58) интересно, буду знать...
спасибо всем за море полезной информации, новые знания сделали меня немного счастливее :) |
|||
60
PRO100 NigGaZ
08.10.13
✎
17:56
|
самое странное что мои 4 запроса из (4) выполняются в 300 раз быстрее чем новый запрос :(
|
|||
61
Mikeware
08.10.13
✎
18:00
|
(6) кагбэ ничего удивительного.
вставь условия по товарам в виртуальные таблицы |
|||
62
КонецЦикла
08.10.13
✎
18:01
|
ВсеНечетал, но вот предлагаю ознакомиться (один из вариантов возникновения ошибки)
Подключение занято до получения результатов для другого hstmt |
|||
63
trad
08.10.13
✎
18:02
|
(54) а как лучше?
|
|||
64
trad
08.10.13
✎
18:06
|
(61) условие по номенклатуре из ON в плане выполнения уйдет в подзапрос от ВТ. Проверено не раз.
|
|||
65
PRO100 NigGaZ
08.10.13
✎
18:19
|
так? |
|||
66
Mikeware
08.10.13
✎
18:25
|
(65) inner - тебя же интересует только те товары, что есть в документе.
Хотя trad против, а я ему верю ибо он крут... |
|||
67
PRO100 NigGaZ
08.10.13
✎
18:34
|
(64) условие по номенклатуре такое?
(66) согласен :) |
|||
68
trad
08.10.13
✎
18:35
|
я не против ибо хуже не будет
|
|||
69
PRO100 NigGaZ
08.10.13
✎
18:55
|
с двумя регистрами
ТЗ = рс10.ВыполнитьИнструкцию(ТекстЗапросаТест); 471 11.342020 51.94 ОстатокНаФирме = рс6.ВыполнитьСкалярный(); 1038 0.202613 0.93 РезервНаФирме = рс7.ВыполнитьСкалярный(); 1038 0.121264 0.56 ОстатокНаСкладе = рс4.ВыполнитьСкалярный(); 519 0.119221 0.55 РезервНаСкладе = рс5.ВыполнитьСкалярный(); 519 0.076368 0.35 с четырьмя замер показывает почти такой же результат ТЗ = рс10.ВыполнитьИнструкцию(ТекстЗапросаТест); 471 12.972334 53.27 ОстатокНаСкладе = рс4.ВыполнитьСкалярный(); 519 0.413398 1.70 ОстатокНаФирме = рс6.ВыполнитьСкалярный(); 1038 0.273864 1.13 РезервНаФирме = рс7.ВыполнитьСкалярный(); 1038 0.124790 0.51 РезервНаСкладе = рс5.ВыполнитьСкалярный(); 519 0.080083 0.33 мои же скалярные все делают намного быстрее :( я не понимаю что тут не так :( |
|||
70
Salimbek
08.10.13
✎
21:11
|
(69) Дальше начинается оптимизация. Первым делом пишешь рс.Отладка(1) до ВыполнитьИнструкцию и смотришь, какой запрос получается в развернутом виде.
|
|||
71
Z1
08.10.13
✎
21:53
|
(70) да какая оптимизация когда в (67) при повторение строк в табличной части будет задвоение ( затроение остатка ),
чего в 4 нет |
|||
72
PRO100 NigGaZ
08.10.13
✎
22:41
|
(71) Почему? О_о (70) да смотрел...
|
|||
73
PRO100 NigGaZ
08.10.13
✎
22:41
|
у меня только резервы кривые еще не победил :(
|
|||
74
PRO100 NigGaZ
08.10.13
✎
22:48
|
причем запросы которые до SUM(CASE идут по отдельности данные правильные возвращают
|
|||
75
PRO100 NigGaZ
09.10.13
✎
00:07
|
вернусь я наверное к выполнению скалярных запросов, где есть инструкция что такое курсор и почему не работает при выполнении (4)
|
|||
76
viktor_vv
09.10.13
✎
01:02
|
Я так тихо подозреваю (4) быстрее, так как нет джойнов и условие по номенклатуре в ВТ типа
Номенклатура = @ВыбНом быстрее выполнится, чем с джойнами. |
|||
77
Salimbek
09.10.13
✎
08:45
|
(76) Думаешь, что перебрать 1С-кой номенклатуру и отправить 100500 запросов к скулю быстрее, чем перебрать эту номенклатуру скулем (select-ом) и собрать данные одним запросом?
(72) Ну если сам смотрел, то положи текст куда-нибудь на pastebin.com чтобы тоже можно было глянуть |
|||
78
Дык ё
09.10.13
✎
09:28
|
(75) курсоры открывать не только 1спп, но и само 1с умеет. тут с умом подходить нужно :-)
|
|||
79
PRO100 NigGaZ
09.10.13
✎
12:56
|
Да, как показал вчерашний день получить все сразу происходит в 8 раз медленнее чем выполняя скалярные запросы :(
|
|||
80
Salimbek
09.10.13
✎
13:10
|
(79) Ты ошибаешься, проблема в неоптимальном плане запроса. И, чтобы посоветовать что-то дельное, я и прошу выложить код из (70) на ПастеБин
|
|||
81
Ёпрст
09.10.13
✎
13:43
|
|Where (Товары.IDDOC = :ВыбДок)
вот это унутрь ВТ запихни, для начала. |
|||
82
viktor_vv
09.10.13
✎
14:44
|
(81) Так там в (67) для верности везде понаставлено :).
| ,inner join $ДокументСтроки.ЗаявкаПокупателя AS Товары With (NOLOCK) on $Товары.Номенклатура = Номенклатура | ,(Товары.IDDOC = :ВыбДок) разве что из условия ВТ в условие соединение перенести "Товары.IDDOC = :ВыбДок", по идее однояйственно, но таки лучше туда. |
|||
83
Salimbek
09.10.13
✎
14:57
|
х.з. я бы сначала простейший запрос с одним регистром бы только потестил, с разными вариантами наложения фильтров, и через временные таблицы попробовал бы, и соединениями различными. Как нашел бы оптимальный по скорости вариант, остальные регистры начал бы подцеплять.
|
|||
84
PRO100 NigGaZ
09.10.13
✎
18:17
|
ок попробую...
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |