powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / [игнор отключен] [закрыт для гостей] / Помогите, запрос с вложенным подзапросом
25 сообщений из 32, страница 1 из 2
Помогите, запрос с вложенным подзапросом
    #36744500
Georgiy L.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
ВЫБРАТЬ
	ПоступлениеТоваров.Ссылка КАК Документ,
	ПоступлениеТоваров.НомерСчетаФактуры,
	ПоступлениеТоваров.ДатаСчетаФактуры,
	ПоступлениеТоваров.Контрагент,
	ВложенныйЗапрос.СуммаВсего
ИЗ
	(ВЫБРАТЬ
		СУММА(ПоступлениеТоваровТовары.СуммаВсего) КАК СуммаВсего
	ИЗ
		Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваровТовары
	ГДЕ
		ПоступлениеТоваровТовары.Ссылка = &Ссылка) КАК ВложенныйЗапрос,
	Документ.ПоступлениеТоваров КАК ПоступлениеТоваров
ГДЕ
	ПоступлениеТоваров.Ссылка В(&мДок)
	И ПоступлениеТоваров.КодСчетФактурыАльфа =  0 

Что здесь не так, строка:

Код: plaintext
ПоступлениеТоваровТовары.Ссылка = &Ссылка) КАК ВложенныйЗапрос,

Хотелось чтобы выглядела так:

Код: plaintext
ПоступлениеТоваровТовары.Ссылка = ПоступлениеТоваров.Ссылка) КАК ВложенныйЗапрос,

Обратите внимание на:

Код: plaintext
ПоступлениеТоваров.Ссылка В(&мДок)

Цель в одну строку вывести данные о документе, т.е. данные шапки и суммы колонок табличной части, не пойму как связать вложенные запрос с подзапросом
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36744571
Georgiy L.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
сорри за глупый вопрос

делается при помощи обычной связи
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36744577
vitkhv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Georgiy L.,

Если я правильно понял вопрос, то Приблизительно вот так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
ВЫБРАТЬ
	ПоступлениеТоваров.Ссылка КАК Документ,
	ПоступлениеТоваров.НомерСчетаФактуры,
	ПоступлениеТоваров.ДатаСчетаФактуры,
	ПоступлениеТоваров.Контрагент,
	ВложенныйЗапрос.СуммаВсего
ИЗ
Документ.ПоступлениеТоваров КАК ПоступлениеТоваров
ЛЕВОЕ СОЕДИНЕНИЕ
	(ВЫБРАТЬ
                      ПоступлениеТоваровТовары.Ссылка,
		СУММА(ПоступлениеТоваров.Товары.СуммаВсего) КАК СуммаВсего
	ИЗ
		Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваровТовары
           СГРУППИРОВАТЬ ПО ПоступлениеТоваровТовары.Ссылка
	) КАК ВложенныйЗапрос 
ПО ПоступлениеТоваров.Ссылка = ВложенныйЗапрос.Ссылка
	
ГДЕ
	ПоступлениеТоваров.Ссылка В(&мДок)
	И ПоступлениеТоваров.КодСчетФактурыАльфа =  0 
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36745022
Naf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот

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

СГРУППИРОВАТЬ ПО
ПоступлениеТоваровУслугТовары.Ссылка,
ПоступлениеТоваровУслугТовары.Ссылка.Контрагент,
ПоступлениеТоваровУслугТовары.Ссылка.ДатаВходящегоДокументаЭлектронногоОбмена,
ПоступлениеТоваровУслугТовары.Ссылка.НомерВходящегоДокументаЭлектронногоОбмена
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36745056
vitkhv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Naf,

Так лучше все таки не писать, непонятно насколько оптимально 1С такой или подобный запрос будет парсить.
В стандартных конфах такого рода код тоже не встречал.
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36750336
nicktcher
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vitkhv,

Жжоте. Делать левое соединение таблицы док-та с его же таб.частью, да ещё при этом которую извлекать вложенным запросом - это что-то с чем-то). Видел разные извраты, но ТАКОГО ...
И Вы ещё рассуждаете про оптимальность парсера?)))
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36750475
vitkhv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nicktchervitkhv,

Жжоте. Делать левое соединение таблицы док-та с его же таб.частью, да ещё при этом которую извлекать вложенным запросом - это что-то с чем-то). Видел разные извраты, но ТАКОГО ...
И Вы ещё рассуждаете про оптимальность парсера?)))

И как будет оптимально по вашему мнению?
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36750829
nicktcher
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vitkhv,

Оптимально всегда избегать по возможности вложенных запросов и левых соединений. Здесь такая возможность есть:

"ВЫБРАТЬ
| ПоступлениеТоваровУслуг.Ссылка,
| ПоступлениеТоваровУслуг.Номер,
| ПоступлениеТоваровУслуг.Дата,
| ПоступлениеТоваровУслуг.Контрагент,
| ПоступлениеТоваровУслуг.Товары.(
| СУММА(Сумма) КАК ИтогоСумма
| ) КАК ТЧ
|ИЗ
| Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
|ГДЕ
| ПоступлениеТоваровУслуг.Ссылка В (&СписокДоков);

//...устанавливаем параметры и всё такое

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
//обработка реквизитов шапки (тривиально, не пишу)
...
//переходим к ТЧ
ВыборкаТЧ = Выборка.ТЧ.Выбрать();
Если ВыборкаТЧ.Следующий() Тогда
ИтогоСумма = ВыборкаТЧ.ИтогоСумма;
КонецЕсли;
КонецЦикла;
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36751148
vitkhv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nicktcher,
Приведенный вами вариант является еще даже более неоптимальным с точки зрения производительности, чем запрос приведенный Naf.

Вот во что 1С парсит приведенный вами запрос:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
INSERT INTO #tt1
(f_2, f_3)
SELECT
_Document257_Q_000_T_001._IDRRef AS f_2,
_Document257_Q_000_T_001._Fld4369RRef AS f_3
FROM
_Document257 _Document257_Q_000_T_001 WITH(NOLOCK)

SELECT
f_2,
f_3,
f_1+ 0 
FROM #tt1 WITH(NOLOCK)

SELECT
CAST(SUM(_Document257_VT4389._Fld4401) AS NUMERIC( 21 , 2 )) AS f_4,
0x00000000 AS _KeyField,
f_1 AS f_1
FROM
#tt1 WITH(NOLOCK)
INNER JOIN _Document257_VT4389 WITH(NOLOCK)
ON f_2 = _Document257_VT4389._Document257_IDRRef
GROUP BY
f_1

TRUNCATE TABLE #tt1

здесь как видите имеется соединение да еще и временная таблица.

Вот во что 1С парсит вариант приведенный Naf:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT
_Document257_VT4389_Q_000_T_001._Document257_IDRRef AS f_1,
_Document257_1._Fld4369RRef AS f_2,
CAST(SUM(_Document257_VT4389_Q_000_T_001._Fld4401) AS NUMERIC( 21 , 2 )) AS f_3
FROM
_Document257_VT4389 _Document257_VT4389_Q_000_T_001 WITH(NOLOCK)
LEFT OUTER JOIN _Document257 _Document257_1 WITH(NOLOCK)
ON _Document257_VT4389_Q_000_T_001._Document257_IDRRef = _Document257_1._IDRRef
GROUP BY
_Document257_VT4389_Q_000_T_001._Document257_IDRRef,
_Document257_1._Fld4369RRef

Основные тормоза в плане запроса наблюдаются вот в этом месте:

Код: plaintext
1.
2.
GROUP BY
_Document257_VT4389_Q_000_T_001._Document257_IDRRef,
_Document257_1._Fld4369RRef


Соответсвенно чем больше будет полей из шапки документа в секции SELECT тем больше их будет в секции GROUP BY , тем больше будет тормозить запрос, мой вариант запроса полностью лишен этого недостатка, ваш только частично, т.к. в вашем варианте во временную таблицу прийдется записывать больше полей.

Хотя его вариант запроса быстрее вашего, при двух полях в секции GROUP BY и SELECT в 1,5 раза!

Мой вариант запроса является самым быстрым из трех приведенных вариантах.

Парсинг моего варианта запроса:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
SELECT
_Document257_Q_000_T_001._IDRRef AS f_1,
_Document257_Q_000_T_001._Fld4373RRef AS f_2,
#V8TblAli1_Q_000_T_002._Q_001_F_001 AS f_3
FROM
_Document257 _Document257_Q_000_T_001 WITH(NOLOCK)
LEFT OUTER JOIN (
SELECT
_Document257_VT4389_Q_001_T_001._Document257_IDRRef AS _Q_001_F_000RRef,
CAST(SUM(_Document257_VT4389_Q_001_T_001._Fld4401) AS NUMERIC( 21 , 2 )) AS _Q_001_F_001
FROM
_Document257_VT4389 _Document257_VT4389_Q_001_T_001 WITH(NOLOCK)
GROUP BY
_Document257_VT4389_Q_001_T_001._Document257_IDRRef
) #V8TblAli1_Q_000_T_002
ON _Document257_Q_000_T_001._IDRRef = #V8TblAli1_Q_000_T_002._Q_001_F_000RRef

При двух полях мой вариант обгоняет, вариант Naf на 10%, ваш вариант в 1,6 раза. При 4х полях мой вариант быстрее варианта Naf в 1,5 раза, быстрее вашего в 2 раза.

Т.е. ваш вариант в теории может обогнать вариант Naf только при 10 - 12 полях, мой же вариат будет по скорости не достижим для обоих вариантов НИКОГДА и не будет зависим от количества полей выбираемых из шапки документа

А вот такие заявления делайте на терзвую голову:
nicktchervitkhv,

Жжоте. Делать левое соединение таблицы док-та с его же таб.частью, да ещё при этом которую извлекать вложенным запросом - это что-то с чем-то). Видел разные извраты, но ТАКОГО...
И Вы ещё рассуждаете про оптимальность парсера?)))

Чуствую растет армия недо SQLщиков воспитанных на синтаксисе запросов 1С 8 версии.

Учитите ANSI SQL 92 и TSQL, ведь если б его знали тогда бы четко понимали, что через две точки сервер не понимает запросов, поэтому все написания в запросах 1С через точки череваты возможной неоптимальностью работы парсера, что приведенный вами вариант явно и показал.

А вот это завявление меня вообще убило напрочь:
nicktchervitkhv,
Оптимально всегда избегать по возможности вложенных запросов и левых соединений.

А вы вообще в теорию реляционных БД хоть одним глазком заглядывали?
Может лучше вообще все на одной таблице сделать, тогда вообще никаких соединений не понадобиться.
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36751236
Программист 1с
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vitkhvУчитите ANSI SQL 92 и TSQL, ведь если б его знали тогда бы четко понимали, что через две точки сервер не понимает запросов, поэтому все написания в запросах 1С через точки череваты возможной неоптимальностью работы парсера, что приведенный вами вариант явно и показал.Вобщето понимает. Но тут уже требуется почти везение и 2 проиндексированных поля по кторому связывается. Но в целом вы правы 1с не рекомендует 2 точки. На экзамене - -0,5 бала.

"Оптимально всегда избегать по возможности вложенных запросов и левых соединений." - 1с рекомендуют только про вложенные запросы. Левые - это конечно чушь.
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36751680
Егоров Александр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
смысл в том, что, например

select ДокументСтроки.Товар.Реквизит
from ДокументСтроки

1С по идее должна развернуть в

select Справочник.Реквизит
from Документ.Строки inner join Справочник on справочник.ID=Документ.Товар...

вмето этого она сливает справочник.ID и справочник.Реквизит во врем.таблицу и джойнит уже с ней... 77 вообще на клиенте лопатит справочник :) Соотв. если уж браться за такие "через две точки" - то разворачивать вторую точку самому...
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36751811
vitkhv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Программист 1сВобщето понимает.

SQL сервер понимает через 2 точки ?

Или nicktcher понимает ANSI SQL 92 ?


Что касается SQL сервера как он может понимать через 2 точки, при не объектном хранении данных?

Что касается nicktcher как он может понимать ANSI SQL 92 если даже видимо не знает, что ТЧ документа и его шапка хранятся в разных таблицах и серверу необходимо обязательно сделать соединения между этими двумя таблицами, чтобы получить, что то из табличной части, как в данном случае. Ан нет 1С опять со своим синтаксисом запросов вводит людей в заблуждение.

Программист 1с"Оптимально всегда избегать по возможности вложенных запросов и левых соединений." - 1с рекомендуют только про вложенные запросы. Левые - это конечно чушь.

Если можно ссылку на то где 1С не рекомендует вложенные запросы в секции JOIN.

На TSQL в секции JOIN отрицательных рекомендаций по использованию вложенных запросов, никогда не слышал, а вот использование вложенных запросов в секции SELECT то да очень сильно не рекомендуется. Хотя 1С вложенные подзапросы в секции SELECT вроде не понимает, пишу вроде т.к. никогда и не пытался их использовать в этой секции, просто где вроде читал, что непонимает.
Может рекомендации 1С связанны с мультиплатформенностью? Скорей всего есть какие то проблемы во вложенных подзапросах с собственным форматом хранения данных от 1С, т.к. в других серверах БД с которыми работает 1С я о таких проблемах не слышал (может конечно плохо слушал ).

Ну и так как я работаю на данном этапе сугубо с MSSQL , а собственный формат 1С использовать вообще не собираюсь и никому не рекомендую (про свой негативный опыт работы с этим форматом я уже писал), поэтому мне такие рекомендации от 1С откровенно побоку т.к. четко знаю во что 1С превратит (отпарсит) запрос 1С в запрос TSQL.

Так, что пишите правильно господа запросы в 1С следуя анотации ANSI SQL 92, а не через 2 точки и не будет проблем с производительностью вложенных подзапросов в секции JOIN.
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36751830
nicktcher
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vitkhv,

Не смешите мои тапочки.
Вы сами ни черта в теории реляционных БД не понимаете, судя по вашим выкладкам))). С вашими соединениями у Вас одни одни и те же таблицы документов в БД минимум за 3 прохода, да ещё соединяться между собой, какие 1,6 раза преимущество Вы откопали??? Вы бредите, любезнейший! Ваши соединения на сотнях и тысячах ссылок будут в РАЗЫ медленнее работать.
Погоняйте профайлером все варианты на больших объемах документов - чтобы ссылок было не 1 или 2, а сотни и тысячи. И с вашими соединениями можете преспокойно пить чаек, в то время как при простом запросе пользователь будет получать итоги за секунды.
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36751836
nicktcher
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"Оптимально всегда избегать по возможности вложенных запросов и левых соединений." - 1с рекомендуют только про вложенные запросы. Левые - это конечно чушь.[/quot]

Вношу поправочку - я ничего не имею против соединений. Я только утверждаю, что запрос без соединений всегда отрабатывает быстрее, чем запрос с соединениями. Зачем городить то, без чего можно легко обойтись?
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36751863
Программист 1с
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vitkhvПрограммист 1сВобщето понимает.

SQL сервер понимает через 2 точки ?

Или nicktcher понимает ANSI SQL 92 ?


Что касается SQL сервера как он может понимать через 2 точки, при не объектном хранении данных?

Что касается nicktcher как он может понимать ANSI SQL 92 если даже видимо не знает, что ТЧ документа и его шапка хранятся в разных таблицах и серверу необходимо обязательно сделать соединения между этими двумя таблицами, чтобы получить, что то из табличной части, как в данном случае. Ан нет 1С опять со своим синтаксисом запросов вводит людей в заблуждение.

Программист 1с"Оптимально всегда избегать по возможности вложенных запросов и левых соединений." - 1с рекомендуют только про вложенные запросы. Левые - это конечно чушь.

Если можно ссылку на то где 1С не рекомендует вложенные запросы в секции JOIN.

На TSQL в секции JOIN отрицательных рекомендаций по использованию вложенных запросов, никогда не слышал, а вот использование вложенных запросов в секции SELECT то да очень сильно не рекомендуется. Хотя 1С вложенные подзапросы в секции SELECT вроде не понимает, пишу вроде т.к. никогда и не пытался их использовать в этой секции, просто где вроде читал, что непонимает.
Может рекомендации 1С связанны с мультиплатформенностью? Скорей всего есть какие то проблемы во вложенных подзапросах с собственным форматом хранения данных от 1С, т.к. в других серверах БД с которыми работает 1С я о таких проблемах не слышал (может конечно плохо слушал ).

Ну и так как я работаю на данном этапе сугубо с MSSQL , а собственный формат 1С использовать вообще не собираюсь и никому не рекомендую (про свой негативный опыт работы с этим форматом я уже писал), поэтому мне такие рекомендации от 1С откровенно побоку т.к. четко знаю во что 1С превратит (отпарсит) запрос 1С в запрос TSQL.

Так, что пишите правильно господа запросы в 1С следуя анотации ANSI SQL 92, а не через 2 точки и не будет проблем с производительностью вложенных подзапросов в секции JOIN.Еще раз говорю - понимает 2 точки (имеется ввиду что правильно составляет план запроса и естественно с несколькими таблицами, а не одной. Тоесть фактически скуль за программиста переписывает правильно запрос без 2 точек). Сам видел 2 запроса. Один из них прекрасно отработал по скорости и не пришлось даже его оптимизировать. Но я уже сказал - что он был приведен как исключение которое иногда работает.

В большой желтой книжке - точно написано про не рекомендуется делать 2 вложенных запроса. А про вобще не делать - новое веяние 8.2 они предлагают заменять на временные таблицы. Причина - гарантированная скорость выполнения запроса в не зависимости от бд. А по скорости - чуть медленнее чем вложенный. Но это процентов 5.


ps Вы зациклились на 2 точках и вложенных. Сходите на эксперта 1с по технологическим вопросам - там больше и интереснее. Особенно про взаимоблокировки.
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36751992
vitkhv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nicktcher
Вношу поправочку - я ничего не имею против соединений. Я только утверждаю, что запрос без соединений всегда отрабатывает быстрее, чем запрос с соединениями. Зачем городить то, без чего можно легко обойтись?

Да и тут же приводите пример там где без соединений не обойтись
Об этом вам уже 3 человека говорят, что там есть и соединения и временная "ненужная" таблица.

nicktcher
Вы сами ни черта в теории реляционных БД не понимаете, судя по вашим выкладкам))). С вашими соединениями у Вас одни одни и те же таблицы документов в БД минимум за 3 прохода, да ещё соединяться между собой, какие 1,6 раза преимущество Вы откопали???


3 прохода? С этого места поподробнее, что за три прохода и по каким таблицам БД в моем варианте запроса? Парсинг есть моего запроса приведен немного выше.


nicktcher
Вы бредите, любезнейший! Ваши соединения на сотнях и тысячах ссылок будут в РАЗЫ медленнее работать.
Погоняйте профайлером все варианты на больших объемах документов - чтобы ссылок было не 1 или 2, а сотни и тысячи. И с вашими соединениями можете преспокойно пить чаек, в то время как при простом запросе пользователь будет получать итоги за секунды.


Да ну? Вы еще более безнадежны чем я думал, доказывая свою правоту любезнейший представляйте аргументы, а не свои умственные выкладки, да еще с оскорбительным поддеткстом.
Вообще будете добры планы запросов в студию, для вашего и моего варианта запросов будет достаточно.
И в представленных планах ткнете меня в 3 прохода носом.
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36752026
vitkhv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Программист 1сЕще раз говорю - понимает 2 точки

Все таки не понятно вы говорите что SQL сервер понимает две точки?

Т.е. на TSQL (не на 1С) можно написать вот так:
SELECT t1.p1.p2 FROM t1 ? И сервер это схамает?

Программист 1с
ps Вы зациклились на 2 точках и вложенных. Сходите на эксперта 1с по технологическим вопросам - там больше и интереснее. Особенно про взаимоблокировки.

Наверное зациклился, но когда залетают в тему и начинают говорить, что дибил и так писать нельзя, на достаточно оптимальный вариант запроса. Причем просто переписанный со старого варианта синтаксиса на новый.
Орать, что ты нифига не понимаешь элементарного, а уже лезеш в парсер.
И тут же приводить пример написания запроса который 1С даже сама не рекомендует к использованию, при этом говорить, что там нет никаких соединений. Уж не знаю как вы, а я зациклился.

А курсы в 1С проходить считаю очень полезным.
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36752108
nicktcher
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vitkhv,

Вы меня достали уже) Мои умственные выкладки основаны на многолетнем коппании в профайлере и в стеке вызовов запросов именно на уровне БД. . И уж, поверьте мне, я не хуже вашего знаю стандарты SQL. Замечу также, что на личности первый именно Вы перешли, когда стали применять выражения типа "недо SQLщики" и т.п. Но я согласен. Давайте обсудим спокойно, без суеты, по пунктам. И приношу свои извинения, если задел чем-то. Надеюсь, что и Вы тоже воздержитесь от уничжительных обращений)).

1) Замечание относительно терминологии. Я обратил внимание, что Вы слово "парсер" применяете к месту и не к месту. Хотя парсер - это лишь распознаватель. Он отрабатывает один раз при распознавании запроса от приложения, транслирует его. И всё, на этом его функция заканчивается и дальше в дело вступают другие механизмы БД. В связи с этим мне неясно, почему говоря об "оптимальности" Вы всё время напираете на парсер. Из эторго я делаю вывод, что либо Вы не понимаете, что есть парсер, либо Вы не понимаете, что есть "оптимальность". Давайте договоримся, что говоря об "оптимальности" запроса мы говорим о скорости выполнения запроса , а не о скорости его распознавания и трансформации парсером . Согласны?

2) Едем дальше. Про соединения. Представьте себе, я знаю, что документы и ТЧ документов хранятся в разных физических таблицах в БД. Соответственно, я также знаю, что при выполнении запроса, в котором извлекаются данные из ТЧ неминуемо имеет место быть внутреннее соединение. Да, скулем создается временная таблица. Ну и что? Кто Вам сказал, что она "ненужная"? И кто Вам сказал, что это сильно скажется на скорости? Я Вам ещё раз говорю - проверьте на большом кол-ве документов. Не надо также выдумывать и додумывать про гипотетическое кол-во полей в запросе. Пусть они определены и не меняются. Понятно, что при отсутствии индекесов по нужным нам полям оптимизатор в БД будет строить планы выполнения на фул сканах, что не есть гут. Причем в любом варианте - и в вашем и в моем. Но только на производительности запроса это в вашем варианте катастрофически отразится, а на моем нет.
Потому что именно в вашем варианте таблица с ТЧ док-та будет сканироваться многократно именно из-за идиотского вложенного запроса. Подумайте сами - фактически таблица с ТЧ у Вас будет прогоняться столько раз, сколько док-тов у Вас имеется в списке ссылок. И на больших массивах док-тов (о чем я и писал уже) у Вас всё умрет просто. А в моем варианте обе таблицы будут обработаны за проход вне зав-сти от кол-ва документов, попадающих в запрос.
Вот так вот. Так что временная таблица здесь не при чем.
Вы просто неверно оценили приоритеты.
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36752168
vitkhv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nicktcher
Замечу также, что на личности первый именно Вы перешли, когда стали применять выражения типа "недо SQLщики" и т.п.

Да но не я подобное первым написал:
nicktcher
Видел разные извраты, но ТАКОГО...
И Вы ещё рассуждаете про оптимальность парсера?)))

не правда же ли?

Причем если вы заметите автор топика спрашивал конкретно как ему написать запрос и пример был именно с подзапросом. Т.к. была попытка написать запрос в старом варианте синтаксиса без соединений я ему такой вариант представил, но уже в новом стиле. Причем автор топика даже не пытался обсуждать производительность.

Что касается моего замечания Naf, замечу что прекрасно понимаю, что вариант представленный Naf SQL сервер не поймет, поэтому не всегда с уверенностью можно сказать как же 1С отпарсит данный вариант запроса. Да и сама 1С так писать не рекомендует. Поэтому считаю мое замечание правомочным.

nicktcher
Давайте обсудим спокойно, без суеты, по пунктам. И приношу свои извинения, если задел чем-то. Надеюсь, что и Вы тоже воздержитесь от уничжительных обращений))

Я вам приношу так же свои извенения если чем то задел. Просто из ваших слов и примеров мне виделось именно незнание.

Ну и конечно конструктивный диалог предпочтительнее, деструктивного конечно.
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36752206
Программист 1с
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vitkhvПрограммист 1сЕще раз говорю - понимает 2 точки

Все таки не понятно вы говорите что SQL сервер понимает две точки?

Т.е. на TSQL (не на 1С) можно написать вот так:
SELECT t1.p1.p2 FROM t1 ? И сервер это схамает?

Программист 1с
ps Вы зациклились на 2 точках и вложенных. Сходите на эксперта 1с по технологическим вопросам - там больше и интереснее. Особенно про взаимоблокировки.

Наверное зациклился, но когда залетают в тему и начинают говорить, что дибил и так писать нельзя, на достаточно оптимальный вариант запроса. Причем просто переписанный со старого варианта синтаксиса на новый.
Орать, что ты нифига не понимаешь элементарного, а уже лезеш в парсер.
И тут же приводить пример написания запроса который 1С даже сама не рекомендует к использованию, при этом говорить, что там нет никаких соединений. Уж не знаю как вы, а я зациклился.

А курсы в 1С проходить считаю очень полезным.Нет не понимает. Я говорил про план запроса - что он может быть идентичным тому, который написан без 2 точек.
Пример контрагент.договор.фигнякакаято.
Будет запрос с 2 таблицами - по контрагентам и договорам.


ps что-то я уже сам запутался в вашем споре. Отчаливаю
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36752237
vitkhv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nicktchervitkhv,
1) Замечание относительно терминологии. Я обратил внимание, что Вы слово "парсер" применяете к месту и не к месту. Хотя парсер - это лишь распознаватель. Он отрабатывает один раз при распознавании запроса от приложения, транслирует его. И всё, на этом его функция заканчивается и дальше в дело вступают другие механизмы БД. В связи с этим мне неясно, почему говоря об "оптимальности" Вы всё время напираете на парсер. Из эторго я делаю вывод, что либо Вы не понимаете, что есть парсер, либо Вы не понимаете, что есть "оптимальность". Давайте договоримся, что говоря об "оптимальности" запроса мы говорим о скорости выполнения запроса , а не о скорости его распознавания и трансформации парсером . Согласны?


Да вы конечно же правы, когда говорите про парсер, в общем случае конечно же.
Но в слово оптимальность я закладываю как скорость обработки ИЗ (в нашем случае Запросы 1С) В (конечный результат понятный серверу БД), так и точность этой обработки , т.е. применимость конечного результата в данном конкретном случае.

Соответственно, что бы не рисковать и облегчить работу парсера необходимо писать запросы максимально приближенные к тому варианту который понимает сервер БД, в моем случае это MS SQL. Синтаксис запросов 1С позволяет такое делать, кроме суперагрегирования.

Поэтому если в данном конкреном случае требуется временная таблица то ее следует описать явно, язык запросов 1С это позволяет, а не использовать приведенное вами описание, т.к. непонятно в итоге как парсер 1С его обработает, т.е. что в итоге мы получим на выходе и насколько данный результат будет применим с точки зрения производительности.
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36752758
vitkhv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nicktchervitkhv,
1) Замечание относительно терминологии. Я обратил внимание, что Вы слово "парсер" применяете к месту и не к месту. Хотя парсер - это лишь распознаватель. Он отрабатывает один раз при распознавании запроса от приложения, транслирует его. И всё, на этом его функция заканчивается и дальше в дело вступают другие механизмы БД. В связи с этим мне неясно, почему говоря об "оптимальности" Вы всё время напираете на парсер. Из эторго я делаю вывод, что либо Вы не понимаете, что есть парсер, либо Вы не понимаете, что есть "оптимальность". Давайте договоримся, что говоря об "оптимальности" запроса мы говорим о скорости выполнения запроса , а не о скорости его распознавания и трансформации парсером . Согласны?


Да вы конечно же правы, когда говорите про парсер, в общем случае конечно же.
Но в слово оптимальность я закладываю как скорость обработки ИЗ (в нашем случае Запросы 1С) В (конечный результат понятный серверу БД), так и точность этой обработки , т.е. применимость конечного результата в данном конкретном случае.

Соответственно, что бы не рисковать и облегчить работу парсера необходимо писать запросы максимально приближенные к тому варианту который понимает сервер БД, в моем случае это MS SQL. Синтаксис запросов 1С позволяет такое делать, кроме суперагрегирования.

Поэтому если в данном конкреном случае требуется временная таблица то ее следует описать явно, язык запросов 1С это позволяет, а не использовать приведенное вами описание, т.к. непонятно в итоге как парсер 1С его обработает, т.е. что в итоге мы получим на выходе и насколько данный результат будет применим с точки зрения производительности.
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36752768
vitkhv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nicktcher
2) Едем дальше.

Ну ж тож едем :

nicktcher
Понятно, что при отсутствии индекесов по нужным нам полям оптимизатор в БД будет строить планы выполнения на фул сканах, что не есть гут. Причем в любом варианте - и в вашем и в моем. Но только на производительности запроса это в вашем варианте катастрофически отразится, а на моем нет.


Теперь планы выполнения вашего варианта запроса и моего при 4 полях в секции SELECT:

Мой запрос 1С:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
|ВЫБРАТЬ
|	ПоступлениеТоваров.Ссылка КАК Документ,
|	ПоступлениеТоваров.Организация,
|	ПоступлениеТоваров.Ответственный,
|	ПоступлениеТоваров.Контрагент,
|	ВложенныйЗапрос.Сумма
|ИЗ
|Документ.ЗаказПокупателя КАК ПоступлениеТоваров
|ЛЕВОЕ СОЕДИНЕНИЕ
|	(ВЫБРАТЬ
|       ПоступлениеТоваровУслугТовары.Ссылка,
|		СУММА(ПоступлениеТоваровУслугТовары.Сумма) КАК Сумма
|	ИЗ
|		Документ.ЗаказПокупателя.Товары КАК ПоступлениеТоваровУслугТовары
|       СГРУППИРОВАТЬ ПО ПоступлениеТоваровУслугТовары.Ссылка
|	) КАК ВложенныйЗапрос 
|ПО ПоступлениеТоваров.Ссылка = ВложенныйЗапрос.Ссылка
|	

|";

Парс моего запроса:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
SELECT
_Document257_Q_000_T_001._IDRRef AS f_1,
_Document257_Q_000_T_001._Fld4373RRef AS f_2,
_Document257_Q_000_T_001._Fld4374RRef AS f_3,
_Document257_Q_000_T_001._Fld4369RRef AS f_4,
#V8TblAli1_Q_000_T_002._Q_001_F_001 AS f_5
FROM
_Document257 _Document257_Q_000_T_001 WITH(NOLOCK)
LEFT OUTER JOIN (
SELECT
_Document257_VT4389_Q_001_T_001._Document257_IDRRef AS _Q_001_F_000RRef,
CAST(SUM(_Document257_VT4389_Q_001_T_001._Fld4401) AS NUMERIC( 21 , 2 )) AS _Q_001_F_001
FROM
_Document257_VT4389 _Document257_VT4389_Q_001_T_001 WITH(NOLOCK)
GROUP BY
_Document257_VT4389_Q_001_T_001._Document257_IDRRef
) #V8TblAli1_Q_000_T_002
ON _Document257_Q_000_T_001._IDRRef = #V8TblAli1_Q_000_T_002._Q_001_F_000RRef

План моего запроса:
Код: plaintext
1.
2.
3.
4.
5.
6.
  
SELECT _Document257_Q_000_T_001._IDRRef AS f_1, _Document257_Q_000_T_001._Fld4373RRef AS f_2, _Document257_Q_000_T_001._Fld4374RRef AS f_3, _Document257_Q_000_T_001._Fld4369RRef AS f_4, #V8TblAli1_Q_000_T_002._Q_001_F_001 AS f_5 FROM _Document257 _Document257_Q_000_T_001 WITH(NOLOCK) LEFT OUTER JOIN ( SELECT _Document257_VT4389_Q_001_T_001._Document257_IDRRef AS _Q_001_F_000RRef, CAST(SUM(_Document257_VT4389_Q_001_T_001._Fld4401) AS NUMERIC( 21 , 2 )) AS _Q_001_F_001 FROM _Document257_VT4389 _Document257_VT4389_Q_001_T_001 WITH(NOLOCK) GROUP BY _Document257_VT4389_Q_001_T_001._Document257_IDRRef ) #V8TblAli1_Q_000_T_002 ON _Document257_Q_000_T_001._IDRRef = #V8TblAli1_Q_000_T_002._Q_001_F_000RRef
  |--Merge Join(Right Outer Join, MERGE:([_Document257_VT4389_Q_001_T_001].[_Document257_IDRRef])=([_Document257_Q_000_T_001].[_IDRRef]), RESIDUAL:([decima].[dbo].[_Document257].[_IDRRef] as [_Document257_Q_000_T_001].[_IDRRef]=[decima].[dbo].[_Document257_VT4389].[_Document257_IDRRef] as [_Document257_VT4389_Q_001_T_001].[_Document257_IDRRef]))
       |--Compute Scalar(DEFINE:([Expr1006]=CONVERT(numeric(21,2),[Expr1004],0)))
       |    |--Stream Aggregate(GROUP BY:([_Document257_VT4389_Q_001_T_001].[_Document257_IDRRef]) DEFINE:([Expr1004]=SUM([decima].[dbo].[_Document257_VT4389].[_Fld4401] as [_Document257_VT4389_Q_001_T_001].[_Fld4401])))
       |         |--Clustered Index Scan(OBJECT:([decima].[dbo].[_Document257_VT4389].[_Documen257_VT4389_IntKeyInd] AS [_Document257_VT4389_Q_001_T_001]), ORDERED FORWARD)
       |--Clustered Index Scan(OBJECT:([decima].[dbo].[_Document257].[PK___Document257__0A0406BE] AS [_Document257_Q_000_T_001]), ORDERED FORWARD)

Ваш запрос 1С:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
|ВЫБРАТЬ
|	ПоступлениеТоваров.Ссылка КАК Документ,
|	ПоступлениеТоваров.Организация,
|	ПоступлениеТоваров.Ответственный,
|	ПоступлениеТоваров.Контрагент,
|	ПоступлениеТоваров.Товары.(
|   СУММА(Сумма) КАК ИтогоСумма
| ) КАК ТЧ
|ИЗ
|Документ.ЗаказПокупателя КАК ПоступлениеТоваров
|	
|";

Парс вашего запроса 1С:

Создается таблица временная таблица #tt1 стакой структурой, ее в анализ планов запроса не включаем:
Код: plaintext
1.
2.
3.
4.
5.
6.
SELECT TOP  0  CAST(0x AS BINARY( 16 )) f_2,
CAST(0x AS BINARY( 16 )) f_3,
CAST(0x AS BINARY( 16 )) f_4,
CAST(0x AS BINARY( 16 )) f_5,
IDENTITY (INT,  1 ,  1 ) f_1
INTO #tt1

вот и сам запрос:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
INSERT INTO #tt1
(f_2, f_3, f_4, f_5)
SELECT
_Document257_Q_000_T_001._IDRRef AS f_2,
_Document257_Q_000_T_001._Fld4373RRef AS f_3,
_Document257_Q_000_T_001._Fld4374RRef AS f_4,
_Document257_Q_000_T_001._Fld4369RRef AS f_5
FROM
_Document257 _Document257_Q_000_T_001 WITH(NOLOCK)

SELECT
f_2,
f_3,
f_4,
f_5,
f_1+ 0 
FROM #tt1 WITH(NOLOCK)


SELECT
CAST(SUM(_Document257_VT4389._Fld4401) AS NUMERIC( 21 , 2 )) AS f_6,
0x00000000 AS _KeyField,
f_1 AS f_1
FROM
#tt1 WITH(NOLOCK)
inner JOIN _Document257_VT4389 WITH(NOLOCK)
ON f_2 = _Document257_VT4389._Document257_IDRRef
GROUP BY
f_1

План вашего варианта запроса:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
INSERT INTO #tt1 (f_2, f_3, f_4, f_5) SELECT _Document257_Q_000_T_001._IDRRef AS f_2, _Document257_Q_000_T_001._Fld4373RRef AS f_3, _Document257_Q_000_T_001._Fld4374RRef AS f_4, _Document257_Q_000_T_001._Fld4369RRef AS f_5 FROM _Document257 _Document257_Q_000_T_001 WITH(NOLOCK)
  |--Table Insert(OBJECT:([tempdb].[dbo].[#tt1]), SET:([tempdb].[dbo].[#tt1].[f_2] = [decima].[dbo].[_Document257].[_IDRRef] as [_Document257_Q_000_T_001].[_IDRRef],[tempdb].[dbo].[#tt1].[f_3] = [decima].[dbo].[_Document257].[_Fld4373RRef] as [_Document257_Q_000_T_001].[_Fld4373RRef],[tempdb].[dbo].[#tt1].[f_4] = [decima].[dbo].[_Document257].[_Fld4374RRef] as [_Document257_Q_000_T_001].[_Fld4374RRef],[tempdb].[dbo].[#tt1].[f_5] = [decima].[dbo].[_Document257].[_Fld4369RRef] as [_Document257_Q_000_T_001].[_Fld4369RRef],[tempdb].[dbo].[#tt1].[f_1] = [Expr1006]))
       |--Compute Scalar(DEFINE:([Expr1006]=getidentity((85575343),(2),NULL)))
            |--Top(ROWCOUNT est 0)
                 |--Clustered Index Scan(OBJECT:([decima].[dbo].[_Document257].[PK___Document257__0A0406BE] AS [_Document257_Q_000_T_001]))
 SELECT f_2, f_3, f_4, f_5, f_1+ 0  FROM #tt1 WITH(NOLOCK)
  |--Compute Scalar(DEFINE:([Expr1004]=[tempdb].[dbo].[#tt1].[f_1]+(0)))
       |--Table Scan(OBJECT:([tempdb].[dbo].[#tt1]))
 SELECT CAST(SUM(_Document257_VT4389._Fld4401) AS NUMERIC( 21 , 2 )) AS f_6, 0x00000000 AS _KeyField, f_1 AS f_1 FROM #tt1 WITH(NOLOCK) inner JOIN _Document257_VT4389 WITH(NOLOCK) ON f_2 = _Document257_VT4389._Document257_IDRRef GROUP BY f_1
  |--Compute Scalar(DEFINE:([Expr1008]=CONVERT(numeric(21,2),[Expr1007],0), [Expr1009]=0x00000000))
       |--Hash Match(Aggregate, HASH:([tempdb].[dbo].[#tt1].[f_1]) DEFINE:([Expr1007]=SUM([decima].[dbo].[_Document257_VT4389].[_Fld4401])))
            |--Hash Match(Inner Join, HASH:([tempdb].[dbo].[#tt1].[f_2])=([decima].[dbo].[_Document257_VT4389].[_Document257_IDRRef]), RESIDUAL:([decima].[dbo].[_Document257_VT4389].[_Document257_IDRRef]=[tempdb].[dbo].[#tt1].[f_2]))
                 |--Table Scan(OBJECT:([tempdb].[dbo].[#tt1]))
                 |--Clustered Index Scan(OBJECT:([decima].[dbo].[_Document257_VT4389].[_Documen257_VT4389_IntKeyInd]))


Так где же в плане моего вариатнта запросов несколько проходов?
Все идет по Clustered Index Scan (по одному на таблицу шапки и таблицу ТЧ), также как и у вас, только у вас дополнительно 2 раза читается временная таблица, в моем варианте такого нет. При этом количество операций ввода - вывода при Clustered Index Scan одинаково, что в вашем, что в моем случае.
Только ваш запрос медленнее выполняется за счет создания не нужной в данном случае ВТ. И ее лишнего чтения вот здесь:

Код: plaintext
1.
2.
3.
4.
5.
6.
SELECT
f_2,
f_3,
f_4,
f_5,
f_1+ 0 
FROM #tt1 WITH(NOLOCK)

Во вложении внешняя обработка на которой проводился тест.
Количество документов в БД 2720, количество строк в ТЧ Товары 14989.
Т.е. в среднем получается по 5.5 строк на документ.
При больших объемах, я думаю, разницы не будет никакой.

Версия 1С 8.1.15, версия УПП 1.2.32

Версия SQL 2005.
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36756556
tiniji
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vitkhv,

ИМХО vitkhv и Naf привели абсолютно почти 2 одинаковых запроса. 10% прирост это наверное громко сказано... Один просто любит SQL и не надеется на 1С. Впрочем правильно и делает.

Получение *.Товары.(.....................
Давно я такого не встречал, впрочем в УТ есть несколько таких древних запросов вроде. Наверное с 8.0 осталось.
У вас УЖЕ только в этой конструкции будет падение производительности
Код: plaintext
1.
2.
3.
4.
5.
6.
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
//обработка реквизитов шапки (тривиально, не пишу)
...
//переходим к ТЧ
ВыборкаТЧ = Выборка.ТЧ.Выбрать();
Если ВыборкаТЧ.Следующий() Тогда

P.S. Если в типовых конфигах куча неоптимальных запросов, то я так понимаю конфигурации пишут нифига не специалисты по Платформе... Ну это просто, вспомнилось...
...
Рейтинг: 0 / 0
Помогите, запрос с вложенным подзапросом
    #36756612
Искандер Двурогий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vitkhvNaf,

Так лучше все таки не писать, непонятно насколько оптимально 1С такой или подобный запрос будет парсить.
В стандартных конфах такого рода код тоже не встречал.

Как раз Naf написал правильнее всех. Именно так и рекомендуют сейчас писать разработчики платформы. А остальные никому не нужными извращениями занимаются.
...
Рейтинг: 0 / 0
25 сообщений из 32, страница 1 из 2
Форумы / [игнор отключен] [закрыт для гостей] / Помогите, запрос с вложенным подзапросом
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]