Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Обычная тема Как оптимизировать? (число прочтений - 1844 )
al_zzz
Senior Member
****
Отсутствует


1C++ ->

Сообщений: 361
Местоположение: Барнаул
Зарегистрирован: 05. Сентября 2009
Пол: Мужской
Как оптимизировать?
12. Мая 2012 :: 04:13
Печать  
Есть задачка - проверять наличие подчиненных документов определенного вида у документов определенного вида, взятых за период(точнее, задачу заключается в поиске самого старого документа, не имеющего подчиненного, или имеющего непроведенный подчиненный документ).
Решил сначала одним способом с помощью вложенного запроса:
Код
Выбрать все
ТекстЗапроса = "-- qryMaker:Просроченные перемещения.2011.11.25.15.38.51
		|SELECT  "+ВидПеремещения+".$ОбщийРеквизит.СтатусПеремещения СтатусПеремещения
		|	, "+ВидПеремещения+".IDDOC [Перемещение $Документ."+ВидПеремещения+"]
		|   , Выборка.Документ     [Документ $Документ]
		|   , Выборка.Документ_вид Документ_вид
		|FROM _1SJOURN AS Журнал With (NOLOCK)
		|	INNER JOIN $Документ."+ВидПеремещения+" AS "+ВидПеремещения+" With (NOLOCK) ON Журнал.IDDOC = "+ВидПеремещения+".IdDoc
		|   Left JOIN (Select ЖурналПодч.IDDOC    Документ,
		|			   ЖурналПодч.IDdocdef Документ_вид,
		|			   Отбор.ParentVal     Основание,
		|			   (ЖурналПодч.CLOSED & 1) Проведен
		|		From _1SCRDOC AS Отбор With (NOLOCK)
		|		Left Join _1SJOURN AS ЖурналПодч With (NOLOCK) On  ЖурналПодч.IDDOC = Отбор.Childid
		|		Where (ЖурналПодч.IDdocdef = $ВидДокумента."+ВидПеремещения+")
		|			   ) As Выборка ON 'O1' + $ВидДокумента36."+ВидПеремещения+"+Журнал.IDDOC = Выборка.Основание
		|WHERE (Журнал.DATE_TIME_IDDOC >= :НачДата)
		|	AND (Журнал.DATE_TIME_IDDOC <= :КонДата~)
		|   AND ((Журнал.CLOSED & 1) = 1)
		|   And ((Выборка.Документ Is Null) Or (Выборка.Проведен = 0))
		|ORDER BY Журнал.DATE_TIME_IDDOC
		|"; 

- выполняется примерно 5 секунд.
  

Каждая система проходит три стадии:&&1) Шумиха&&2) Неразбериха&&3) Поиск виновных (собственно, рабочий процесс)&&4) Наказание невиновных&&5) Награждение непричастных&& В.М. Глушков
Наверх
 
IP записан
 
al_zzz
Senior Member
****
Отсутствует


1C++ ->

Сообщений: 361
Местоположение: Барнаул
Зарегистрирован: 05. Сентября 2009
Пол: Мужской
Re: Как оптимизировать?
Ответ #1 - 12. Мая 2012 :: 04:15
Печать  
Решил вторым способом, используя временную таблицу:
Код
Выбрать все
рс = СоздатьОбъект("ODBCRecordSet");
	//1. Удаляем таблицу, если с таким именем уже имеется
		ТекстЗапроса="
		|set nocount on
		|if exists (select * from %База%..sysobjects where id=object_id('%База%..%Имя%') and sysstat & 0xf = 3 )
		|  drop table %База%..%Имя%;
		|set nocount off
		|";
		ИмяБазы = КаталогИБ();
		ИмяБазы = СтрЗаменить(Нрег(КаталогИБ()),"h:\","");
		ИмяБазы = СтрЗаменить(ИмяБазы,"\","");
		Если ИмяБазы = "db" Тогда
			ИмяБазы = "office";
		КонецЕсли;
		ИмяТаблицы = "ПодчиненныеПеремещения";
		Текстзапроса = СтрЗаменить(Текстзапроса,"%База%",ИмяБазы);
		Текстзапроса = СтрЗаменить(Текстзапроса,"%Имя%",ИмяТаблицы);
		рс.Выполнить(ТекстЗапроса);
		// 2. Создаем таблицу заново
		рс.Выполнить("Create Table ПодчиненныеПеремещения (Документ Char(13), Документ_вид Int, Основание Char(23))");
		// 3. Укладываем в неё все проведенные подчиненные перемещения нужного вида
		ТекстЗапроса = "-- qryMaker:Просроченные перемещения.2011.11.25.15.38.51
		|Insert into ПодчиненныеПеремещения
		|Select ЖурналПодч.IDDOC    Документ,
		|			   ЖурналПодч.IDdocdef Документ_вид,
		|			   Отбор.ParentVal     Основание
		|		From _1SCRDOC AS Отбор With (NOLOCK)
		|		Left Join _1SJOURN AS ЖурналПодч With (NOLOCK) On  ЖурналПодч.IDDOC = Отбор.Childid
		|		Where (ЖурналПодч.IDdocdef = $ВидДокумента."+ВидПеремещения+")
		|			And ((ЖурналПодч.CLOSED & 1)=1)
		|";
		тз = рс.Выполнить(ТекстЗапроса);
		// 4. Получаем таблицу непринятых данного вида
		ТекстЗапроса = "-- qryMaker:Просроченные перемещения.2011.11.25.15.38.51
		|SELECT  "+ВидПеремещения+".$ОбщийРеквизит.СтатусПеремещения СтатусПеремещения
		|	, "+ВидПеремещения+".IDDOC [Перемещение $Документ."+ВидПеремещения+"]
		|   , Выборка.Документ     [Документ $Документ]
		|   , Выборка.Документ_вид Документ_вид
		|FROM _1SJOURN AS Журнал With (NOLOCK)
		|	INNER JOIN $Документ."+ВидПеремещения+" AS "+ВидПеремещения+" With (NOLOCK) ON Журнал.IDDOC = "+ВидПеремещения+".IdDoc
		|   Left JOIN ПодчиненныеПеремещения As Выборка ON 'O1' + $ВидДокумента36."+ВидПеремещения+"+Журнал.IDDOC = Выборка.Основание
		|WHERE (Журнал.DATE_TIME_IDDOC >= :НачДата)
		|	AND (Журнал.DATE_TIME_IDDOC <= :КонДата~)
		|   AND ((Журнал.CLOSED & 1) = 1)
		|   And (Выборка.Документ Is Null)
		|ORDER BY Журнал.DATE_TIME_IDDOC
		|";

		рс.УстановитьТекстовыйПараметр("НачДата", Дата_-МинусДней-60);
		рс.УстановитьТекстовыйПараметр("КонДата", Дата_-МинусДней);
		тз = рс.ВыполнитьИнструкцию(ТекстЗапроса);
		Возврат тз; 

- прироста не наблюдается - те же 5 секунд. А действие предполагает частое выполнение и 5 секунд - недопустимо долго. Как можно ускорить выполнение?
  

Каждая система проходит три стадии:&&1) Шумиха&&2) Неразбериха&&3) Поиск виновных (собственно, рабочий процесс)&&4) Наказание невиновных&&5) Награждение непричастных&& В.М. Глушков
Наверх
 
IP записан
 
Salimbek
God Member
*****
Отсутствует



Сообщений: 862
Зарегистрирован: 06. Июня 2006
Пол: Мужской
Re: Как оптимизировать?
Ответ #2 - 12. Мая 2012 :: 04:26
Печать  
Посмотри, для начала тут
Обрати особое внимание на то, как формируется условие для попадания в индекс.
И еще я вижу у тебя 2 запроса, какой из них сколько времени занимает?
  
Наверх
ICQ  
IP записан
 
Salimbek
God Member
*****
Отсутствует



Сообщений: 862
Зарегистрирован: 06. Июня 2006
Пол: Мужской
Re: Как оптимизировать?
Ответ #3 - 12. Мая 2012 :: 04:35
Печать  
Кроме того, вытаскивать всю таблицу Подчиненных документов во временную (пусть и с условием на вид документа) - это, имхо, неправильно. Сам посуди - объемы информации у тебя растут, соответственно будет расти и объем выборки.
  
Наверх
ICQ  
IP записан
 
Salimbek
God Member
*****
Отсутствует



Сообщений: 862
Зарегистрирован: 06. Июня 2006
Пол: Мужской
Re: Как оптимизировать?
Ответ #4 - 12. Мая 2012 :: 04:38
Печать  
  
Наверх
ICQ  
IP записан
 
al_zzz
Senior Member
****
Отсутствует


1C++ ->

Сообщений: 361
Местоположение: Барнаул
Зарегистрирован: 05. Сентября 2009
Пол: Мужской
Re: Как оптимизировать?
Ответ #5 - 12. Мая 2012 :: 05:17
Печать  
Ускорил исходя из логики задачи - так как подчиненные документы нужны для документов взятых за период, в выборку попадают подчиненные, заведенные не ранее начала периода выборки родителей. То есть, теперь не всю таблицу беру, а только с начальной даты. В итоге время выполнения от 0,5 до 2-ух секунд. Это уже приемлемо.
Salimbek, спасибо за помощь!
  

Каждая система проходит три стадии:&&1) Шумиха&&2) Неразбериха&&3) Поиск виновных (собственно, рабочий процесс)&&4) Наказание невиновных&&5) Награждение непричастных&& В.М. Глушков
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Как оптимизировать?
Ответ #6 - 12. Мая 2012 :: 07:24
Печать  
(1) Если нужен документ только одного вида то и поставть
это ограничение на _1sjourn

ps тогда и
     INNER JOIN $Документ."+ВидПеремещения+" AS "+ВидПеремещения+" With (NOLOCK) ON Журнал.IDDOC = "+ВидПеремещения+".IdDoc

получается ненужным. Вот и получишь выигрыш.
  
Наверх
 
IP записан
 
al_zzz
Senior Member
****
Отсутствует


1C++ ->

Сообщений: 361
Местоположение: Барнаул
Зарегистрирован: 05. Сентября 2009
Пол: Мужской
Re: Как оптимизировать?
Ответ #7 - 12. Мая 2012 :: 10:15
Печать  
Z1 писал(а) 12. Мая 2012 :: 07:24:
(1) Если нужен документ только одного вида то и поставть
это ограничение на _1sjourn

ps тогда и
     INNER JOIN $Документ."+ВидПеремещения+" AS "+ВидПеремещения+" With (NOLOCK) ON Журнал.IDDOC = "+ВидПеремещения+".IdDoc

получается ненужным. Вот и получишь выигрыш.

Ок! Точно!
  

Каждая система проходит три стадии:&&1) Шумиха&&2) Неразбериха&&3) Поиск виновных (собственно, рабочий процесс)&&4) Наказание невиновных&&5) Награждение непричастных&& В.М. Глушков
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать