Перейти к содержимому


- - - - -

(РЕШЕНО) Запрос вешает комп :( "Недостаточно памяти"


Сообщений в теме: 13

#1 Onotoley

    Частый гость


  • 57 сообщений

Отправлено 06 февраля 2012 - 14:32

Доброго времени суток!
Есть запрос следующего вида:

ВЫБРАТЬ
СпрНоменклатура.Ссылка КАК Номенклатура,
Продажи1.КоличествоОборот КАК Оборот1,
Продажи2.КоличествоОборот КАК Оборот2,
Продажи3.КоличествоОборот КАК Оборот3,
Продажи4.КоличествоОборот КАК Оборот4,
ПродажиВсего.КоличествоОборот КАК ОборотВсего,
ПродажиЗаГод.КоличествоОборот КАК ОборотЗаГод,
ПродажиЗаГодТек.КоличествоОборот КАК ОборотЗаГодТек,
СНачалаПродаж.КоличествоОборот КАК ОборотСНачалаПродаж,
Остатки.КоличествоОстаток КАК Остаток,
ОстаткиРезерв.КоличествоОстаток КАК ОстатокРезерв,
Остатки.КоличествоОстаток - ОстаткиРезерв.КоличествоОстаток КАК ЧистыйОстаток
ИЗ
Справочник.Номенклатура КАК СпрНоменклатура
  ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(&ДатаНач1, &ДатаКон1, Период, ) КАК Продажи1
  ПО (Продажи1.Номенклатура = СпрНоменклатура.Ссылка)
  ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(&ДатаНач2, &ДатаКон2, Период, ) КАК Продажи2
  ПО (Продажи2.Номенклатура = СпрНоменклатура.Ссылка)
  ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(&ДатаНач3, &ДатаКон3, Период, ) КАК Продажи3
  ПО (Продажи3.Номенклатура = СпрНоменклатура.Ссылка)
  ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(&ДатаНач4, &ДатаКон4, Период, ) КАК Продажи4
  ПО (Продажи4.Номенклатура = СпрНоменклатура.Ссылка)
  ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(&ПериодНач, &ПериодКон, Период, ) КАК ПродажиВсего
  ПО (ПродажиВсего.Номенклатура = СпрНоменклатура.Ссылка)
  ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(&ГодНач, &ГодКон, Период, ) КАК ПродажиЗаГод
  ПО (ПродажиЗаГод.Номенклатура = СпрНоменклатура.Ссылка)
  ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(&ГодНачТек, &ГодКонТек, Период, ) КАК ПродажиЗаГодТек
  ПО (ПродажиЗаГодТек.Номенклатура = СпрНоменклатура.Ссылка)
  ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(, , Период, ) КАК СНачалаПродаж
  ПО (СНачалаПродаж.Номенклатура = СпрНоменклатура.Ссылка)
  ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(&ПериодКон, ) КАК Остатки
  ПО (Остатки.Номенклатура = СпрНоменклатура.Ссылка)
  ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки(&ПериодКон, ) КАК ОстаткиРезерв
  ПО (ОстаткиРезерв.Номенклатура = СпрНоменклатура.Ссылка)
ГДЕ
(ПродажиВсего.КоличествоОборот <> 0
   ИЛИ ПродажиЗаГод.КоличествоОборот <> 0
   ИЛИ ПродажиЗаГодТек.КоличествоОборот <> 0
   ИЛИ Остатки.КоличествоОстаток <> 0)
и бла-бла-бла.
Запрос работает не быстро, но работает.

Добавили в него еще условий:

И (НЕ Продажи1.Контрагент.Код В (&Клиенты))
И (НЕ Продажи2.Контрагент.Код В (&Клиенты))
И (НЕ Продажи3.Контрагент.Код В (&Клиенты))
И (НЕ Продажи4.Контрагент.Код В (&Клиенты))
И (НЕ ПродажиВсего.Контрагент.Код В (&Клиенты))
И (НЕ ПродажиЗаГод.Контрагент.Код В (&Клиенты))
И (НЕ ПродажиЗаГодТек.Контрагент.Код В (&Клиенты))
И (НЕ СНачалаПродаж.Контрагент.Код В (&Клиенты))

В Массиве "Клиенты" всего два контрагента, но этого вполне достаточно :))) На компе 6гиг оперативы, выполнение обработки медленно, но верно жрет оперативку до самого конца. В итоге выдает сообщение "Недостаточно памяти" и 1С закрывается :(
Можно как-то оптимизировать данный запрос? Или выполнить его каким-то образом на сервере? Ускорит-ли это выполнение запроса?

#2 BabySG

    Любитель программирования


  • 12 220 сообщений

Отправлено 06 февраля 2012 - 14:37

И запрос ужасный и условие просто ж..а для оптимизатора.
Вердикт: выкинуть такой запроса вообще.

Теперь давайте начнем с простого: что за задача?
Вывести обороты за разные периоды? Чем не подходит СКД, где это все делается одним запросом и без левых соединений?

ЗЫ. А этот запрос надо сразу было переписать на пакетные, условие сразу вынести в пакет и оперировать ссылками.
Ничто так сильно не укрепляет веру в человека, как ПРЕДОПЛАТА!

#3 Onotoley

    Частый гость


  • 57 сообщений

Отправлено 06 февраля 2012 - 14:46

Да, отчет показывает обороты за 4 месяца, за 4 месяца в сумме, за год текущий и за год прошлый.
К сожалению, не очень силен в запросах, ибо самоучка :blush: Пока пытаюсь переделать то, что досталось. Позже буду делать все с нуля.

#4 Tiger86

    Ветеран


  • 1 076 сообщений

Отправлено 06 февраля 2012 - 16:09

чем больше условий на такой запрос наложите, тем быстрее память заканчиваться будет... Если вы будете все равно переделывать заново, то думаю, самое время начать сейчас. Поробуйте разбить запрос на пакеты - они побыстрее работают (по крайней мере мне так всегда казалось).

З.Ы. не заметила, что вам уже посоветовали пакеты...

Сообщение отредактировал Tiger86: 06 февраля 2012 - 16:10

хотите сказать спасибо? жмите Изображение

#5 BabySG

    Любитель программирования


  • 12 220 сообщений

Отправлено 06 февраля 2012 - 16:29

Просмотр сообщенияTiger86 (06 февраля 2012 - 16:09) писал:

Поробуйте разбить запрос на пакеты - они побыстрее работают (по крайней мере мне так всегда казалось).
Правильно казалось.
Вообще, самое первичное в таком запросе - устранение левых соеднинений с виртуальны таблицами. В реальности такие соединения в такое превращаются...
Ничто так сильно не укрепляет веру в человека, как ПРЕДОПЛАТА!

#6 Onotoley

    Частый гость


  • 57 сообщений

Отправлено 06 февраля 2012 - 16:55

Пример хотя-бы одного оборота можете привести?

#7 BabySG

    Любитель программирования


  • 12 220 сообщений

Отправлено 06 февраля 2012 - 17:24

Не понял вопроса. Этот как?
Ничто так сильно не укрепляет веру в человека, как ПРЕДОПЛАТА!

#8 Наташа

    Ветеран


  • 1 478 сообщений

Отправлено 06 февраля 2012 - 17:35

Я бы еще условие по контрагенту добавила в параметр виртуальной таблицы.

РегистрНакопления.Продажи.Обороты(&ДатаНач, &ДатаКон, Период, Контрагент В &Массив)


#9 BabySG

    Любитель программирования


  • 12 220 сообщений

Отправлено 06 февраля 2012 - 17:42

Пример с пакетом (на первую таблицу сразу с условием)
"ВЫБРАТЬ
    Контрагенты.Ссылка КАК Контрагент
ПОМЕСТИТЬ Клиенты
ИЗ
    Справочник.Контрагенты КАК Контрагенты
ГДЕ
    Контрагенты.Код В(&Клиенты)
;

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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    СпрНоменклатура.Ссылка КАК Номенклатура,
    Продажи1.КоличествоОборот КАК Оборот1,
    Продажи2.КоличествоОборот КАК Оборот2,
    Продажи3.КоличествоОборот КАК Оборот3,
    Продажи4.КоличествоОборот КАК Оборот4,
    ПродажиВсего.КоличествоОборот КАК ОборотВсего,
    ПродажиЗаГод.КоличествоОборот КАК ОборотЗаГод,
    ПродажиЗаГодТек.КоличествоОборот КАК ОборотЗаГодТек,
    СНачалаПродаж.КоличествоОборот КАК ОборотСНачалаПродаж,
    Остатки.КоличествоОстаток КАК Остаток,
    ОстаткиРезерв.КоличествоОстаток КАК ОстатокРезерв,
    Остатки.КоличествоОстаток - ОстаткиРезерв.КоличествоОстаток КАК ЧистыйОстаток
ИЗ
    Справочник.Номенклатура КАК СпрНоменклатура
        ЛЕВОЕ СОЕДИНЕНИЕ Оборот1 КАК Продажи1
        ПО (Продажи1.Номенклатура = СпрНоменклатура.Ссылка)
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(&ДатаНач2, &ДатаКон2, Период, ) КАК Продажи2
        ПО (Продажи2.Номенклатура = СпрНоменклатура.Ссылка)
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(&ДатаНач3, &ДатаКон3, Период, ) КАК Продажи3
        ПО (Продажи3.Номенклатура = СпрНоменклатура.Ссылка)
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(&ДатаНач4, &ДатаКон4, Период, ) КАК Продажи4
        ПО (Продажи4.Номенклатура = СпрНоменклатура.Ссылка)
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(&ПериодНач, &ПериодКон, Период, ) КАК ПродажиВсего
        ПО (ПродажиВсего.Номенклатура = СпрНоменклатура.Ссылка)
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(&ГодНач, &ГодКон, Период, ) КАК ПродажиЗаГод
        ПО (ПродажиЗаГод.Номенклатура = СпрНоменклатура.Ссылка)
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(&ГодНачТек, &ГодКонТек, Период, ) КАК ПродажиЗаГодТек
        ПО (ПродажиЗаГодТек.Номенклатура = СпрНоменклатура.Ссылка)
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(, , Период, ) КАК СНачалаПродаж
        ПО (СНачалаПродаж.Номенклатура = СпрНоменклатура.Ссылка)
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(&ПериодКон, ) КАК Остатки
        ПО (Остатки.Номенклатура = СпрНоменклатура.Ссылка)
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки(&ПериодКон, ) КАК ОстаткиРезерв
        ПО (ОстаткиРезерв.Номенклатура = СпрНоменклатура.Ссылка)
ГДЕ
    (ПродажиВсего.КоличествоОборот <> 0
            ИЛИ ПродажиЗаГод.КоличествоОборот <> 0
            ИЛИ ПродажиЗаГодТек.КоличествоОборот <> 0
            ИЛИ Остатки.КоличествоОстаток <> 0)"

Ничто так сильно не укрепляет веру в человека, как ПРЕДОПЛАТА!

#10 Onotoley

    Частый гость


  • 57 сообщений

Отправлено 07 февраля 2012 - 14:10

Спасибо за пример! Буду пробовать разобраться :)

#11 Onotoley

    Частый гость


  • 57 сообщений

Отправлено 07 февраля 2012 - 15:03

Поругайте плиз то, что удалось сваять. Я правильно все понял?


"ВЫБРАТЬ
	Контрагенты.Ссылка КАК Контрагент
ПОМЕСТИТЬ Клиенты
ИЗ
	Справочник.Контрагенты КАК Контрагенты
ГДЕ
	Контрагенты.Код В(&Клиенты)
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ПродажиОбороты.Номенклатура,
	ПродажиОбороты.КоличествоОборот
ПОМЕСТИТЬ Оборот1
ИЗ
	РегистрНакопления.Продажи.Обороты(
			&ДатаНач1,
			&ДатаКон1,
			Период,
			(НЕ Контрагент В
					(ВЫБРАТЬ
						Клиенты.Контрагент
					ИЗ
						Клиенты КАК Клиенты))) КАК ПродажиОбороты
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ПродажиОбороты.Номенклатура,
	ПродажиОбороты.КоличествоОборот
ПОМЕСТИТЬ Оборот2
ИЗ
	РегистрНакопления.Продажи.Обороты(
			&ДатаНач2,
			&ДатаКон2,
			Период,
			(НЕ Контрагент В
					(ВЫБРАТЬ
						Клиенты.Контрагент
					ИЗ
						Клиенты КАК Клиенты))) КАК ПродажиОбороты
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ПродажиОбороты.Номенклатура,
	ПродажиОбороты.КоличествоОборот
ПОМЕСТИТЬ Оборот3
ИЗ
	РегистрНакопления.Продажи.Обороты(
			&ДатаНач3,
			&ДатаКон3,
			Период,
			(НЕ Контрагент В
					(ВЫБРАТЬ
						Клиенты.Контрагент
					ИЗ
						Клиенты КАК Клиенты))) КАК ПродажиОбороты
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ПродажиОбороты.Номенклатура,
	ПродажиОбороты.КоличествоОборот
ПОМЕСТИТЬ Оборот4
ИЗ
	РегистрНакопления.Продажи.Обороты(
			&ДатаНач4,
			&ДатаКон4,
			Период,
			(НЕ Контрагент В
					(ВЫБРАТЬ
						Клиенты.Контрагент
					ИЗ
						Клиенты КАК Клиенты))) КАК ПродажиОбороты
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ПродажиОбороты.Номенклатура,
	ПродажиОбороты.КоличествоОборот
ПОМЕСТИТЬ ОборотВсего
ИЗ
	РегистрНакопления.Продажи.Обороты(
			&ПериодНач,
			&ПериодКон,
			Период,
			(НЕ Контрагент В
					(ВЫБРАТЬ
						Клиенты.Контрагент
					ИЗ
						Клиенты КАК Клиенты))) КАК ПродажиОбороты
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ПродажиОбороты.Номенклатура,
	ПродажиОбороты.КоличествоОборот
ПОМЕСТИТЬ ОборотЗаГод
ИЗ
	РегистрНакопления.Продажи.Обороты(
			&ГодНач,
			&ГодКон,
			Период,
			(НЕ Контрагент В
					(ВЫБРАТЬ
						Клиенты.Контрагент
					ИЗ
						Клиенты КАК Клиенты))) КАК ПродажиОбороты
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ПродажиОбороты.Номенклатура,
	ПродажиОбороты.КоличествоОборот
ПОМЕСТИТЬ ОборотЗаГодТек
ИЗ
	РегистрНакопления.Продажи.Обороты(
			&ГодНачТек,
			&ГодКонТек,
			Период,
			(НЕ Контрагент В
					(ВЫБРАТЬ
						Клиенты.Контрагент
					ИЗ
						Клиенты КАК Клиенты))) КАК ПродажиОбороты
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ПродажиОбороты.Номенклатура,
	ПродажиОбороты.КоличествоОборот
ПОМЕСТИТЬ ОборотСНачалаПродаж
ИЗ
	РегистрНакопления.Продажи.Обороты(
			,
			,
			Период,
			(НЕ Контрагент В
					(ВЫБРАТЬ
						Клиенты.Контрагент
					ИЗ
						Клиенты КАК Клиенты))) КАК ПродажиОбороты
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	СпрНоменклатура.Ссылка КАК Номенклатура,
	Продажи1.КоличествоОборот КАК Оборот1,
	Продажи2.КоличествоОборот КАК Оборот2,
	Продажи3.КоличествоОборот КАК Оборот3,
	Продажи4.КоличествоОборот КАК Оборот4,
	ПродажиВсего.КоличествоОборот КАК ОборотВсего,
	ПродажиЗаГод.КоличествоОборот КАК ОборотЗаГод,
	ПродажиЗаГодТек.КоличествоОборот КАК ОборотЗаГодТек,
	СНачалаПродаж.КоличествоОборот КАК ОборотСНачалаПродаж,
	Остатки.КоличествоОстаток КАК Остаток,
	ОстаткиРезерв.КоличествоОстаток КАК ОстатокРезерв,
	Остатки.КоличествоОстаток - ОстаткиРезерв.КоличествоОстаток КАК ЧистыйОстаток
ИЗ
	Справочник.Номенклатура КАК СпрНоменклатура
		ЛЕВОЕ СОЕДИНЕНИЕ Оборот1 КАК Продажи1
		ПО (Продажи1.Номенклатура = СпрНоменклатура.Ссылка)
		ЛЕВОЕ СОЕДИНЕНИЕ Оборот2 КАК Продажи2
		ПО (Продажи2.Номенклатура = СпрНоменклатура.Ссылка)
		ЛЕВОЕ СОЕДИНЕНИЕ Оборот3 КАК Продажи3
		ПО (Продажи3.Номенклатура = СпрНоменклатура.Ссылка)
		ЛЕВОЕ СОЕДИНЕНИЕ Оборот4 КАК Продажи4
		ПО (Продажи4.Номенклатура = СпрНоменклатура.Ссылка)
		ЛЕВОЕ СОЕДИНЕНИЕ ОборотВсего КАК ПродажиВсего
		ПО (ПродажиВсего.Номенклатура = СпрНоменклатура.Ссылка)
		ЛЕВОЕ СОЕДИНЕНИЕ ОборотЗаГод КАК ПродажиЗаГод
		ПО (ПродажиЗаГод.Номенклатура = СпрНоменклатура.Ссылка)
		ЛЕВОЕ СОЕДИНЕНИЕ ОборотЗаГодТек КАК ПродажиЗаГодТек
		ПО (ПродажиЗаГодТек.Номенклатура = СпрНоменклатура.Ссылка)
		ЛЕВОЕ СОЕДИНЕНИЕ ОборотСНачалаПродаж КАК СНачалаПродаж
		ПО (СНачалаПродаж.Номенклатура = СпрНоменклатура.Ссылка)
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(&ПериодКон, ) КАК Остатки
		ПО (Остатки.Номенклатура = СпрНоменклатура.Ссылка)
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки(&ПериодКон, ) КАК ОстаткиРезерв
		ПО (ОстаткиРезерв.Номенклатура = СпрНоменклатура.Ссылка)
ГДЕ
	(ПродажиВсего.КоличествоОборот <> 0
			ИЛИ ПродажиЗаГод.КоличествоОборот <> 0
			ИЛИ ПродажиЗаГодТек.КоличествоОборот <> 0
			ИЛИ Остатки.КоличествоОстаток <> 0)"

Результат выводится за 10 секунд.

#12 Tiger86

    Ветеран


  • 1 076 сообщений

Отправлено 07 февраля 2012 - 15:11

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

#13 BabySG

    Любитель программирования


  • 12 220 сообщений

Отправлено 07 февраля 2012 - 15:15

Просмотр сообщенияOnotoley (07 февраля 2012 - 15:03) писал:

Поругайте плиз то, что удалось сваять. Я правильно все понял?
Результат выводится за 10 секунд.
Таблицу остатков по такому же принципу сделайте
Если 10 сек устраивает - то все нормально :)

Просмотр сообщенияTiger86 (07 февраля 2012 - 15:11) писал:

я бы первый запрос убрала и добавила в регистр условие как Наташа вам указала. Иначе вы тратите время на вложенные запросы в каждом пакете. Попробуйте, может так быстрее дело пойдет.
Передача массива в данном случае будет почти тоже самое.
И еще обратите внимание, что там поиск по коду идет, а не по ссылке.
Ничто так сильно не укрепляет веру в человека, как ПРЕДОПЛАТА!

#14 Onotoley

    Частый гость


  • 57 сообщений

Отправлено 07 февраля 2012 - 15:27

Просмотр сообщенияBabySG (07 февраля 2012 - 15:15) писал:

Если 10 сек устраивает - то все нормально :)

Не просто устраивает, а - :yahoo: :yahoo: :yahoo:
Еще раз пасиба за помощь!!!





Количество пользователей, читающих эту тему: 1

0 пользователей, 1 гостей, 0 анонимных