Переключение на Главную Страницу Страницы: [1]  ОтправитьПечать
Горячая тема (более 10 ответов) Опимизация. part 5687 (число прочтений - 5084 )
Rubin
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 70
Зарегистрирован: 31. Июля 2007
Опимизация. part 5687
30. Октября 2007 :: 08:50
Печать  
Код
Выбрать все
SELECT
	СпрКонтр.ID as [Клиент $Справочник.Контрагенты],
	Докум as [Докум $Документ],
	Докум_вид as Докум_вид,
	SUM(НачДолг) as НачДолг,
	SUM(РасхДолг) as РасхДолг,
	SUM(ПрихДолг) as ПрихДолг,
	SUM(НачДолгПост) as НачДолгПост,
	SUM(РасхДолгПост) as РасхДолгПост,
	SUM(ПрихДолгПост) as ПрихДолгПост,
	SUM(НачДолг)+SUM(ПрихДолг)-SUM(РасхДолг) as КонДолг,
	SUM(НачДолгПост)+SUM(ПрихДолгПост)-SUM(РасхДолгПост) as КонДолгПост
FROM
	SELECT
		Клиент,
		SUM(НачДолг) as НачДолг,
		SUM(РасхДолг) as РасхДолг,
		SUM(ПрихДолг) as ПрихДолг,
		SUM(НачДолгПост) as НачДолгПост,
		SUM(РасхДолгПост) as РасхДолгПост,
		SUM(ПрихДолгПост) as ПрихДолгПост,
		'' as Докум,
		'' as Докум_вид
	FROM (
		SELECT
			Клиент,
			НачДолг as НачДолг,
			РасхДолг as РасхДолг,
			ПрихДолг as ПрихДолг,
			0 as НачДолгПост,
			0 as РасхДолгПост,
			0 as ПрихДолгПост
		FROM (
			//Регистр итогов по покупателям
			SELECT
				$ОстаткиПер.Клиент as Клиент,
				$ОстаткиПер.Долг as НачДолг,
				0 as РасхДолг,
				0 as ПрихДолг
			FROM
				$РегистрИтоги.ВзаиморасчетыПокупателей as ОстаткиПер
 			WHERE
				period = :НачалоПрошПериода
				AND $ОстаткиПер.Фирма = :УсловиеФирма
				AND $ОстаткиПер.Клиент IN (
					SELECT $ВидСправочника36.Контрагенты+Контр1.id as id
					FROM $Справочник.Контрагенты as Контр1
					LEFT JOIN $Справочник.Контрагенты as Контр2 On Контр2.ID = Контр1.ParentID
					WHERE Контр1.id "+УслКлиенты+" OR Контр2.id "+УслКлиенты+" OR Контр2.ParentID "+УслКлиенты+")
			UNION ALL

			//Регистр оборотов до даты нач по покупателям
			SELECT
				$ОстаткиНаДату.Клиент,
				CASE WHEN ОстаткиНаДату.debkred = 0 THEN $ОстаткиНаДату.Долг ELSE -$ОстаткиНаДату.Долг END,
				0,
				0
			FROM
				$Регистр.ВзаиморасчетыПокупателей as ОстаткиНаДату
			INNER JOIN
				_1SJourn as Журн On Журн.IDDoc = ОстаткиНаДату.IDDoc
					AND Журн.Date_Time_IDDoc >= :КонецПрошПериода AND Журн.Date_Time_IDDoc < :ДатаНач2
			WHERE
				$ОстаткиНаДату.Фирма = :УсловиеФирма
 				AND $ОстаткиНаДату.Клиент IN (
					SELECT $ВидСправочника36.Контрагенты+Контр1.id as id
					FROM $Справочник.Контрагенты as Контр1
					LEFT JOIN $Справочник.Контрагенты as Контр2 On Контр2.ID = Контр1.ParentID
					WHERE Контр1.id "+УслКлиенты+" OR Контр2.id "+УслКлиенты+" OR Контр2.ParentID "+УслКлиенты+")

			UNION ALL

			SELECT
				$Обороты1.Клиент,
				0,
				(Обороты1.debkred)*$Обороты1.Долг,
				(1-Обороты1.debkred)*$Обороты1.Долг
			FROM
				$Регистр.ВзаиморасчетыПокупателей as Обороты1
			INNER JOIN
				_1SJourn as Журн On Журн.IDDoc = Обороты1.IDDoc
					AND Журн.Date_Time_IDDoc BETWEEN :ДатаНач AND:ДатаКон~
			WHERE
				$Обороты1.Фирма = :УсловиеФирма
				AND $Обороты1.Клиент IN (
					SELECT $ВидСправочника36.Контрагенты+Контр1.id as id
					FROM $Справочник.Контрагенты as Контр1
					LEFT JOIN $Справочник.Контрагенты as Контр2 On Контр2.ID = Контр1.ParentID
					WHERE Контр1.id "+УслКлиенты+" OR Контр2.id "+УслКлиенты+" OR Контр2.ParentID "+УслКлиенты+")
			) as Остатки

		UNION ALL

		SELECT
			$ВидСправочника36.Контрагенты + Клиент,
			0 as НачДолг,
			0,
			0,
			НачДолгПост,
			РасхДолгПост,
			ПрихДолгПост
		FROM (
			//Регистр итогов по поставщикам
			SELECT
				$ОстаткиПерПост.Клиент as Клиент,
				$ОстаткиПерПост.Долг as НачДолгПост,
				0 as РасхДолгПост,
				0 as ПрихДолгПост
			FROM
				$РегистрИтоги.ВзаиморасчетыПоставщиков as ОстаткиПерПост
			WHERE
				period = :НачалоПрошПериода AND
				$ОстаткиПерПост.Фирма = :УсловиеФирма
				AND $ОстаткиПерПост.Клиент IN (
					SELECT Контр1.id as id
					FROM $Справочник.Контрагенты as Контр1
					LEFT JOIN $Справочник.Контрагенты as Контр2 On Контр2.ID = Контр1.ParentID
					WHERE Контр1.id "+УслКлиенты+" OR Контр2.id "+УслКлиенты+" OR Контр2.ParentID "+УслКлиенты+")

			UNION ALL

			//регистр оборостов до даты нач по поставщикам
			SELECT
				$ОстаткиНаДату2.Клиент,
				CASE WHEN ОстаткиНаДату2.debkred = 0 THEN $ОстаткиНаДату2.Долг ELSE -$ОстаткиНаДату2.Долг END as НачДолгПост,
				0,
				0
			FROM
				$Регистр.ВзаиморасчетыПоставщиков as ОстаткиНаДату2
			INNER JOIN
				_1SJourn as Журн On Журн.IDDoc = ОстаткиНаДату2.IDDoc
					AND Журн.Date_Time_IDDoc >= :КонецПрошПериода AND Журн.Date_Time_IDDoc < :ДатаНач,
			WHERE
				 $ОстаткиНаДату2.Фирма = :УсловиеФирма
				AND $ОстаткиНаДату2.Клиент IN (
					SELECT Контр1.id as id
					FROM $Справочник.Контрагенты as Контр1
					LEFT JOIN $Справочник.Контрагенты as Контр2 On Контр2.ID = Контр1.ParentID
					WHERE Контр1.id "+УслКлиенты+" OR Контр2.id "+УслКлиенты+" OR Контр2.ParentID "+УслКлиенты+")

			UNION ALL

			SELECT
				$Обороты2.Клиент,
				0,
				(Обороты2.debkred)*$Обороты2.Долг,
				(1-Обороты2.debkred)*$Обороты2.Долг
			FROM
				$Регистр.ВзаиморасчетыПоставщиков as Обороты2
			INNER JOIN
				_1SJourn as Журн On Журн.IDDoc = Обороты2.IDDoc
					"AND Журн.Date_Time_IDDoc BETWEEN :ДатаНач AND :ДатаКон~
			WHERE
				 $Обороты2.Фирма = :УсловиеФирма
				AND $Обороты2.Клиент IN (
					SELECT Контр1.id as id
					FROM $Справочник.Контрагенты as Контр1
					LEFT JOIN $Справочник.Контрагенты as Контр2 On Контр2.ID = Контр1.ParentID
					WHERE Контр1.id "+УслКлиенты+" OR Контр2.id "+УслКлиенты+" OR Контр2.ParentID "+УслКлиенты+")
		) as Остатки
	) ВсеВзаиморасч
	GROUP BY Клиент 


  
Наверх
 
IP записан
 
Rubin
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 70
Зарегистрирован: 31. Июля 2007
Re: Опимизация. part 5687
Ответ #1 - 30. Октября 2007 :: 08:54
Печать  
Код
Выбрать все
	UNION ALL

	SELECT
		Клиент,
		0,
		SUM(РасхДолг),
		SUM(ПрихДолг),
		0,
		SUM(РасхДолгПост),
		SUM(ПрихДолгПост),
		Докум,
		Докум_вид
	FROM (
		SELECT
			$Обороты1.Клиент as Клиент,
			(Обороты1.debkred)*$Обороты1.Долг as РасхДолг,
			(1-Обороты1.debkred)*$Обороты1.Долг as ПрихДолг,
			0,
			0,
			Журн.IDDoc as Докум,
			Журн.IDDocDef as Докум_вид
		FROM
			$Регистр.ВзаиморасчетыПокупателей as Обороты1
		INNER JOIN
			_1SJourn as Журн On Журн.IDDoc = Обороты1.IDDoc
				AND Журн.Date_Time_IDDoc BETWEEN :ДатаНач AND :ДатаКон~
		WHERE
			$Обороты1.Фирма = :УсловиеФирма
			AND $Обороты1.Клиент IN (
				SELECT $ВидСправочника36.Контрагенты+Контр1.id as id
				FROM $Справочник.Контрагенты as Контр1
				LEFT JOIN $Справочник.Контрагенты as Контр2 On Контр2.ID = Контр1.ParentID
				WHERE Контр1.id "+УслКлиенты+" OR Контр2.id "+УслКлиенты+" OR Контр2.ParentID "+УслКлиенты+")

		UNION ALL

		SELECT
			$ВидСправочника36.Контрагенты+$Обороты2.Клиент as Клиент,
			0,
			0,
			(1-Обороты2.debkred)*$Обороты2.Долг,
			(Обороты2.debkred)*$Обороты2.Долг,
			Журн.IDDoc as Докум,
			Журн.IDDocDef as Докум_вид
		FROM
			$Регистр.ВзаиморасчетыПоставщиков as Обороты2
		INNER JOIN
			_1SJourn as Журн On Журн.IDDoc = Обороты2.IDDoc
				AND Журн.Date_Time_IDDoc BETWEEN :ДатаНач AND :ДатаКон~
		WHERE
			$Обороты2.Фирма = :УсловиеФирма
			AND $Обороты2.Клиент IN (
				SELECT $ВидСправочника36.Контрагенты+Контр1.id as id
				FROM $Справочник.Контрагенты as Контр1
				LEFT JOIN $Справочник.Контрагенты as Контр2 On Контр2.ID = Контр1.ParentID
				WHERE Контр1.id "+УслКлиенты+" OR Контр2.id "+УслКлиенты+" OR Контр2.ParentID "+УслКлиенты+")
		) as Все
		GROUP BY Клиент,Докум,Докум_вид
	) ВсеВзаиморасч
	INNER JOIN
		$Справочник.Контрагенты as СпрКонтр On ($ВидСправочника36.Контрагенты + СпрКонтр.ID) = Клиент
	GROUP BY СпрКонтр.Descr,СпрКонтр.ID,Докум,Докум_вид
	ORDER BY СпрКонтр.Descr,СпрКонтр.ID
) 



Если что, извиняюсь, что много. Смысл такой... В верхнем посте выбираются взаимрасчёты, сгруппированные по клиентам... В этом - группировка по документам... Когда работает только верхняя часть, по времени нормально. Как только выполняется запрос верхний+нижний тормозит заметно.. Может лёгким взглядом увидите что неправильное? Ещё мне не нравится реализация фильтра по контрагентам.. Но по другому не придумывается что-то...
  
Наверх
 
IP записан
 
alexdd
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 347
Зарегистрирован: 25. Июня 2007
Re: Опимизация. part 5687
Ответ #2 - 30. Октября 2007 :: 09:52
Печать  
ВТ РегистрОстатки принципиально не используешь?Улыбка
  
Наверх
 
IP записан
 
Rubin
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 70
Зарегистрирован: 31. Июля 2007
Re: Опимизация. part 5687
Ответ #3 - 30. Октября 2007 :: 09:57
Печать  
Мне так проще... От ВТ смысл, я думаю, не изменится.. ВТ ведь это по сути тот же текст, что и у меня
  
Наверх
 
IP записан
 
ev-kov
God Member
*****
Отсутствует



Сообщений: 694
Зарегистрирован: 27. Декабря 2006
Пол: Мужской
Re: Опимизация. part 5687
Ответ #4 - 30. Октября 2007 :: 10:08
Печать  
А если контрагентов уложить в множество до использования в where, скорость повысится как думаете ?
  

Информация - то, что снижает неопределенность в какой-либо области и очень важно не ошибиться областью в наш информационный век!
Наверх
 
IP записан
 
Rubin
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 70
Зарегистрирован: 31. Июля 2007
Re: Опимизация. part 5687
Ответ #5 - 30. Октября 2007 :: 10:11
Печать  
Я так пробовал.. Укладка объектов (без выполнения самого запроса) заняла больше времени, чем выполнение этого запроса..
ЗЫ. В справочнике контрагентов 4000 элементов, кстати )))
  
Наверх
 
IP записан
 
ev-kov
God Member
*****
Отсутствует



Сообщений: 694
Зарегистрирован: 27. Декабря 2006
Пол: Мужской
Re: Опимизация. part 5687
Ответ #6 - 30. Октября 2007 :: 10:12
Печать  
Rubin писал(а) 30. Октября 2007 :: 10:11:
Я так пробовал.. Укладка объектов (без выполнения самого запроса) заняла больше времени, чем выполнение этого запроса..

укладывал во временную таблицу или в множество ?
  

Информация - то, что снижает неопределенность в какой-либо области и очень важно не ошибиться областью в наш информационный век!
Наверх
 
IP записан
 
Rubin
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 70
Зарегистрирован: 31. Июля 2007
Re: Опимизация. part 5687
Ответ #7 - 30. Октября 2007 :: 10:21
Печать  
Код
Выбрать все
	ТекстЗапроса = "
		|	SELECT Контр1.id as id
		|	FROM $Справочник.Контрагенты as Контр1
		|	LEFT JOIN $Справочник.Контрагенты as Контр2 On Контр2.ID = Контр1.ParentID
		|	WHERE Контр1.id "+УслКлиенты+" OR Контр2.id "+УслКлиенты+" OR Контр2.ParentID "+УслКлиенты;
	ТЗ = ЗапросОбъект.ВыполнитьИнструкцию(ТекстЗапроса);
	СЗ = СоздатьОбъект("СписокЗначений");
	ТЗ.Выгрузить(СЗ);
	ЗапросОбъект.УложитьСписокОбъектов13(СЗ,"#СЗ");	 



Эта штука делается 24 секунды (при том что вышеизложенный запрос - не более 5ти уж точно)).. Щас попробую "УложитьСписокОбъектов"
Ну на самом деле, наверно всё-таки укдадка - это не выход... ((
  
Наверх
 
IP записан
 
ev-kov
God Member
*****
Отсутствует



Сообщений: 694
Зарегистрирован: 27. Декабря 2006
Пол: Мужской
Re: Опимизация. part 5687
Ответ #8 - 30. Октября 2007 :: 10:22
Печать  
Rubin писал(а) 30. Октября 2007 :: 10:21:
Код
Выбрать все
	ТекстЗапроса = "
		|	SELECT Контр1.id as id
		|	FROM $Справочник.Контрагенты as Контр1
		|	LEFT JOIN $Справочник.Контрагенты as Контр2 On Контр2.ID = Контр1.ParentID
		|	WHERE Контр1.id "+УслКлиенты+" OR Контр2.id "+УслКлиенты+" OR Контр2.ParentID "+УслКлиенты;
	ТЗ = ЗапросОбъект.ВыполнитьИнструкцию(ТекстЗапроса);
	СЗ = СоздатьОбъект("СписокЗначений");
	ТЗ.Выгрузить(СЗ);
	ЗапросОбъект.УложитьСписокОбъектов13(СЗ,"#СЗ");	 



Эта штука делается 24 секунды (при том что вышеизложенный запрос - не более 5ти уж точно)).. Щас попробую "УложитьСписокОбъектов"

Это во временную таблицу ...
скока элементов укладывает ?
  

Информация - то, что снижает неопределенность в какой-либо области и очень важно не ошибиться областью в наш информационный век!
Наверх
 
IP записан
 
Rubin
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 70
Зарегистрирован: 31. Июля 2007
Re: Опимизация. part 5687
Ответ #9 - 30. Октября 2007 :: 10:24
Печать  
Допустим на вскидку, ну, допустим, тыщщи 3.. Ну неее. Укладка здесь мне кажется не поможет
  
Наверх
 
IP записан
 
ev-kov
God Member
*****
Отсутствует



Сообщений: 694
Зарегистрирован: 27. Декабря 2006
Пол: Мужской
Re: Опимизация. part 5687
Ответ #10 - 30. Октября 2007 :: 10:32
Печать  
Rubin писал(а) 30. Октября 2007 :: 10:24:
Допустим на вскидку, ну, допустим, тыщщи 3.. Ну неее. Укладка здесь мне кажется не поможет

Контр2.ID = Контр1.ParentID Условие на левое соединение нужно ужесточить
Контр2.ID = Контр1.ParentID AND Контр2.isfolder = 2
  

Информация - то, что снижает неопределенность в какой-либо области и очень важно не ошибиться областью в наш информационный век!
Наверх
 
IP записан
 
Rubin
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 70
Зарегистрирован: 31. Июля 2007
Re: Опимизация. part 5687
Ответ #11 - 30. Октября 2007 :: 10:34
Печать  
Кстати, хорошая идея Улыбка
  
Наверх
 
IP записан
 
ev-kov
God Member
*****
Отсутствует



Сообщений: 694
Зарегистрирован: 27. Декабря 2006
Пол: Мужской
Re: Опимизация. part 5687
Ответ #12 - 30. Октября 2007 :: 10:36
Печать  
Rubin писал(а) 30. Октября 2007 :: 10:34:
Кстати, хорошая идея Улыбка

А то ж  Подмигивание
  

Информация - то, что снижает неопределенность в какой-либо области и очень важно не ошибиться областью в наш информационный век!
Наверх
 
IP записан
 
Rubin
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 70
Зарегистрирован: 31. Июля 2007
Re: Опимизация. part 5687
Ответ #13 - 30. Октября 2007 :: 12:02
Печать  
Ну а ещё идеи какие-нить у кого-нить есть? Если в результате отчёта выбирается много строк, то по сравнению с 1с-ким мой работает быстрее.. Но если фильтр задан например по одному контретному контрагенту, то медленнее (((
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Опимизация. part 5687
Ответ #14 - 30. Октября 2007 :: 12:13
Печать  
Rubin писал(а) 30. Октября 2007 :: 12:02:
Ну а ещё идеи какие-нить у кого-нить есть? Если в результате отчёта выбирается много строк, то по сравнению с 1с-ким мой работает быстрее.. Но если фильтр задан например по одному контретному контрагенту, то медленнее (((

ну если у тебя только один клиент то
GROUP BY Клиент  можно убрать
также тебе не нужен
ORDER BY СпрКонтр.Descr,СпрКонтр.ID
а вместо
GROUP BY СпрКонтр.Descr,СпрКонтр.ID,Докум,Докум_вид
будет
GROUP BY Докум,Докум_вид
а некоторые iner join по клиенту тоже вроде можно убрать
  
Наверх
 
IP записан
 
Rubin
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 70
Зарегистрирован: 31. Июля 2007
Re: Опимизация. part 5687
Ответ #15 - 30. Октября 2007 :: 12:20
Печать  
Улыбка Ну это я для примера привёл - 1 клиент.. Это универсальный отчёт, где может быть в фильтре подобран 1 элемент или множество элементов. В том и проблема.. Я могу предусмотреть ситуацию, когда фильтр по одному контрагенту, но она уже не будет работать, если в множ. фильтре пользователь подберёт 2х контрагентов.. Вот и ищу глобальное решение...
  
Наверх
 
IP записан
 
Вадимко
God Member
*****
Отсутствует


Нам бы чего про ОдноЦэ...

Сообщений: 1048
Местоположение: Минск
Зарегистрирован: 24. Мая 2006
Пол: Мужской
Re: Опимизация. part 5687
Ответ #16 - 30. Октября 2007 :: 15:53
Печать  
При использовании ВТ все же меньше шансов получить низкую скорость Улыбка
К тому же можно юзать обратный расчет
Далее... при большом списке в Уложить... можно использовать вложенный запрос
А текст не смотрел, звиняюсь (к тому же непонятна структура регистров)
  

Кампутер, кофе и сигареты - это очень плохо для моего здоровья...
Наверх
IP записан
 
ADirks
1c++ developer
1c++ moderator
Отсутствует


А нужны ли мы нам?

Сообщений: 692
Местоположение: Новосибирск
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Опимизация. part 5687
Ответ #17 - 31. Октября 2007 :: 05:17
Печать  
Я бы с ходу порекомендовал поставить в регистрах быстрый отбор движений - тогда не нужно будет связывание с _1sjourn. А для быстрого отбора контрагентов (и вообще элементов справочников) по группам посмотри в http://www.1cpp.ru/forum/YaBB.pl?num=1153469047. ; Хотя, возможно это чересчур глобально  Улыбка.  Но на практике проверено, и прекрасно себя зарекомендовало.
И ещё очень полезно смотреть на планы выполнения запросов в QA. После достаточно продолжительной медитации начинают полезные мысли в голову приходить Улыбка
  
Наверх
 
IP записан
 
Rubin
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 70
Зарегистрирован: 31. Июля 2007
Re: Опимизация. part 5687
Ответ #18 - 31. Октября 2007 :: 06:24
Печать  
ADirks писал(а) 31. Октября 2007 :: 05:17:
После достаточно продолжительной медитации начинают полезные мысли в голову приходить Улыбка


))) Этим-то я с утра и позанимаюсь.
ЗЫ. Спсб за ссылку
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 
ОтправитьПечать