Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Горячая тема (более 10 ответов) 1sqlite.  Продолжаю обучаться. Наткнулся на одну неприятность... (число прочтений - 3166 )
palpetrovich
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 31
Зарегистрирован: 23. Ноября 2010
1sqlite.  Продолжаю обучаться. Наткнулся на одну неприятность...
02. Декабря 2010 :: 12:52
Печать  
в приведенном ниже коде почему-то последний вид документа не попадает в результат работы запроса

Код
Выбрать все
Функция ПолучитьСписокДоков(ИмяРеквизита)
	Перем Реквизит;
	СписокДоков.УдалитьВсе();
	Для Индекс=1 По Метаданные.Документ() Цикл
		ВидДокумента = Метаданные.Документ(Индекс).Идентификатор;

		Если Реквизит.Выбран()=1 Тогда
			Если Реквизит.Вид="" Тогда
				СписокДоков.ДобавитьЗначение(ВидДокумента, "");
			Иначе
				СписокДоков.ДобавитьЗначение(ВидДокумента, ":ВидСправочника."+Реквизит.Вид+"||");
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	Возврат СписокДоков;
КонецФункции

//=====================================
	текст="
		|Select
		|    Таб.Документ [Док :Документ],
		|    Таб.Товар [Товар :Справочник]
		|From
		|(";
		ДокументИмя = " Документ";
		ТоварИмя = " Товар";
		Для инд=1 По СписокДоков.РазмерСписка() Цикл
			Если инд=2 Тогда
				ДокументИмя = "";
				ТоварИмя = "";
			КонецЕсли;
			РеквизитВид = "";
			ТекВид = СписокДоков.ПолучитьЗначение(инд, РеквизитВид);
			текст=текст+"
			|SELECT
			|	Док.iddoc,
			|   :ВидДокумента."+ТекВид+"||Док.iddoc" + ДокументИмя +",
			|   " + РеквизитВид + "Док.ТМЦ" + ТоварИмя + "
			|   FROM [DocumentLines."+ТекВид+"] Док
			|		LEFT JOIN _1SJourn as Жур ON Жур.IDDOC=Док.IDDoc
			|	 	WHERE Док.ТМЦ in (select val from ВыбрТовар)
			|		AND	Жур.date between @ДатаНач and @ДатаКон
			|UNION ALL";
		КонецЦикла;
		текст= Лев(текст, СтрДлина(текст) - СтрДлина("UNION ALL")) + ") Таб"; 




в СписокДоков этот  ВидДокумента есть!
где я неправ, почему так может быть?
  
Наверх
 
IP записан
 
palpetrovich
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 31
Зарегистрирован: 23. Ноября 2010
Re: 1sqlite.  Продолжаю обучаться. Наткнулся на одну неприятность...
Ответ #1 - 02. Декабря 2010 :: 13:12
Печать  
ограничил двумя видами, Счет - не попадает Печаль
Код
Выбрать все
Select
    Таб.Документ [Док :Документ],
    Таб.Товар [Товар :Справочник]
From
(
SELECT
	Док.iddoc,
   :ВидДокумента.РасходнаяНакладная||Док.iddoc Документ,
   :ВидСправочника.ТМЦ||Док.ТМЦ Товар
   FROM [DocumentLines.РасходнаяНакладная] Док
		LEFT JOIN _1SJourn as Жур ON Жур.IDDOC=Док.IDDoc
	 	WHERE Док.ТМЦ in (select val from ВыбрТовар)
		AND	Жур.date between @ДатаНач and @ДатаКон
UNION ALL
SELECT
	Док.iddoc,
   :ВидДокумента.Счет||Док.iddoc,
   Док.ТМЦ
   FROM [DocumentLines.Счет] Док
		LEFT JOIN _1SJourn as Жур ON Жур.IDDOC=Док.IDDoc
	 	WHERE Док.ТМЦ in (select val from ВыбрТовар)
		AND	Жур.date between @ДатаНач and @ДатаКон
) Таб
 

  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: 1sqlite.  Продолжаю обучаться. Наткнулся на одну неприятность...
Ответ #2 - 02. Декабря 2010 :: 13:20
Печать  
palpetrovich писал(а) 02. Декабря 2010 :: 12:52:
где я неправ, почему так может быть?

А список не из 2-х видов состоит? Улыбка у тебя же ограничения в коде стоит!
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
palpetrovich
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 31
Зарегистрирован: 23. Ноября 2010
Re: 1sqlite.  Продолжаю обучаться. Наткнулся на одну неприятность...
Ответ #3 - 02. Декабря 2010 :: 13:33
Печать  
artbear писал(а) 02. Декабря 2010 :: 13:20:
А список не из 2-х видов состоит? Улыбка у тебя же ограничения в коде стоит!


это я специально ограничил, для проверки

в общем нашел причину.
Не попадают те докумены, в котрых Товар - не Справочник.ТМЦ, а просто Справочник
Причем именно на проверке WHERE..., ибо без нее попадают все
т.е. следующий код - не пашет:
Код
Выбрать все
|SELECT
|Док.IDDoc [Докум :Документ.Счет],
|Док.ТМЦ [Товар :Справочник],
|FROM [DocumentLines.Счет] Док
|WHERE Док.ТМЦ = @ВыбрТовар
запрос.УстановитьПараметр("@ВыбрТовар", ВыбрТМЦ);
 




как это можно обойти?
  
Наверх
 
IP записан
 
orefkov
1c++ developer
1c++ moderator
Отсутствует


I Love YaBB 2!

Сообщений: 896
Зарегистрирован: 20. Мая 2006
Re: 1sqlite.  Продолжаю обучаться. Наткнулся на одну неприятность...
Ответ #4 - 02. Декабря 2010 :: 14:24
Печать  
Для таких доков делай
Код
Выбрать все
WHERE substr(Док.ТМЦ, 1, 4) = :ВидСправочника.ТМЦ and  substr(Док.ТМЦ, 5, 9) in (select val from ВыбрТовар
 

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


1C++ rocks!

Сообщений: 31
Зарегистрирован: 23. Ноября 2010
Re: 1sqlite.  Продолжаю обучаться. Наткнулся на одну неприятность...
Ответ #5 - 02. Декабря 2010 :: 14:44
Печать  
orefkov писал(а) 02. Декабря 2010 :: 14:24:
Для таких доков делай
Код
Выбрать все
WHERE substr(Док.ТМЦ, 1, 4) = :ВидСправочника.ТМЦ and  substr(Док.ТМЦ, 5, 9) in (select val from ВыбрТовар
 



Сделал так, работает
Код
Выбрать все
		текст="
		|Select
		|    Таб.Документ [Док :Документ],
		|    Таб.Товар [Товар :Справочник]
		|From
		|(";
		ДокументИмя = " Документ";
		ТоварИмя = " Товар";
		Для инд=1 По СписокДоков.РазмерСписка() Цикл
			Если инд=2 Тогда
				ДокументИмя = "";
				ТоварИмя = "";
			КонецЕсли;
			РеквизитВид = "";
			ТекВид = СписокДоков.ПолучитьЗначение(инд, РеквизитВид);
			Если РеквизитВид = "" Тогда
				УсловиеОтбора = " substr(Док.ТМЦ, 1, 4) = :ВидСправочника.ТМЦ and  substr(Док.ТМЦ, 5, 9) in (select val from ВыбрТовар)";
			Иначе
				УсловиеОтбора = " Док.ТМЦ in (select val from ВыбрТовар)";
			КонецЕсли;
			текст=текст+"
			|SELECT
			|	Док.iddoc,
			|   :ВидДокумента."+ТекВид+"||Док.iddoc" + ДокументИмя +",
			|   " + РеквизитВид + "Док.ТМЦ" + ТоварИмя + "
			|   FROM [DocumentLines."+ТекВид+"] Док
			|		LEFT JOIN _1SJourn as Жур ON Жур.IDDOC=Док.IDDoc
			|	 WHERE" + УсловиеОтбора + "
			|		AND	Жур.date between @ДатаНач and @ДатаКон
			|UNION ALL";
		КонецЦикла;
		текст= Лев(текст, СтрДлина(текст) - СтрДлина("UNION ALL")) + ") Таб";
 



Спасибо!
  
Наверх
 
IP записан
 
palpetrovich
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 31
Зарегистрирован: 23. Ноября 2010
Re: 1sqlite.  Продолжаю обучаться. Наткнулся на одну неприятность...
Ответ #6 - 03. Декабря 2010 :: 10:03
Печать  
мдя, наверное все-таки мягко-говоря нерациональный запрос получился... замерял время (период - месяц по группе товаров), такие результаты :
1sqlite. Начало подготовки текста. Запрос.Выполнить: 11:44:29
1sqlite.  Конец: 11:44:34
количество строк = 487  


а код:
Код
Выбрать все
	Сообщить(" Начало: "+ ТекущееВремя());  
	Для инд=1 По СписокДоков.РазмерСписка() Цикл    
		ТекВид = СписокДоков.ПолучитьЗначение(инд);	  

		Док = СоздатьОбъект("Документ." + ТекВид);    
		Док.ВыбратьДокументы(ВыбНачПериода, ВыбКонПериода);
		Пока Док.ПолучитьДокумент() = 1 Цикл
			Док.ВыбратьСтроки();
			Пока Док.ПолучитьСтроку() = 1 Цикл
				Если ПроверкаНаВхождение(Док.ТМЦ)=1 Тогда    
					тз.НоваяСтрока();
					тз.Док = Док.ТекущийДокумент();
					тз.ТМЦ = Док.ТМЦ;
				КонецЕсли;
			КонецЦикла;
		КонецЦикла;
	КонецЦикла;
	Сообщить("  Конец: "+ ТекущееВремя() + " количество строк = " + тз.КоличествоСтрок());
	тз.ВыбратьСтроку();  
 


дает:
Начало: 11:44:41
Конец: 11:44:43
количество строк = 487


период - квартал, по группе товаров
1sqlite. Начало. Запрос.Выполнить: 11:54:29
1sqlite.  Конец: 11:54:34 количество строк = 1507

перебор:
Начало: 11:54:39
Конец: 11:54:43 количество строк = 1507


период - полугодие, по группе товаров
1sqlite. Начало. Запрос.Выполнить: 11:55:46
1sqlite.  Конец: 11:55:51 количество строк = 2899

перебор:
Начало: 11:55:54
Конец: 11:56:00 количество строк = 2899


период - полугодие, по ОДНОМУ товароу
1sqlite. Начало. Запрос.Выполнить: 11:57:06
1sqlite.  Конец: 11:57:07 количество строк = 6

перебор:
Начало: 11:57:10
Конец: 11:57:12 количество строк = 6


Количество ТМЦ в тестируемой базе - около 24000, Количество проанализированных документов за полугодие - 6668
  
Наверх
 
IP записан
 
Eprst
God Member
*****
Отсутствует



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: 1sqlite.  Продолжаю обучаться. Наткнулся на одну неприятность...
Ответ #7 - 03. Декабря 2010 :: 12:02
Печать  
Какой-то хнёй маешься бесполезной.
Вся аналитика есть в табличке движения регистра.
Как правило.
Полный перебор всех табличных частей всех видов документов вообще не упал.
  
Наверх
 
IP записан
 
palpetrovich
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 31
Зарегистрирован: 23. Ноября 2010
Re: 1sqlite.  Продолжаю обучаться. Наткнулся на одну неприятность...
Ответ #8 - 03. Декабря 2010 :: 12:24
Печать  
Eprst писал(а) 03. Декабря 2010 :: 12:02:
Какой-то хнёй маешься бесполезной.
Вся аналитика есть в табличке движения регистра.
Как правило.
Полный перебор всех табличных частей всех видов документов вообще не упал.


Дык,  конечно хнёй, кто-ж спорит?!  Подмигивание   ...говорю-ж -- просто учусь я "прямым запросам" ....пока вставляет  Круглые глаза
зы: там задачка была - найти товар во сех доках где он может быть, независимо от того, проведен док или нет...
  
Наверх
 
IP записан
 
orefkov
1c++ developer
1c++ moderator
Отсутствует


I Love YaBB 2!

Сообщений: 896
Зарегистрирован: 20. Мая 2006
Re: 1sqlite.  Продолжаю обучаться. Наткнулся на одну неприятность...
Ответ #9 - 06. Декабря 2010 :: 06:08
Печать  
Для начала более точно замеряй время:
Код
Выбрать все
тНач = _GetPerformanceCounter();
..... Твой код
тКон = _GetPerformanceCounter();
Сообщить("Время выполнения " + (тКон - тНач) + " мсек";
 


Ну и попробуй перед выполнением основного запроса сделать такой запрос
Код
Выбрать все
create index onВыбрТовар on ВыбрТовар(val)
 


Ой, че-то глянул твой запрос внимательнее - мама дорогая, вся таблица строк ПОЛНОСТЬЮ шерстится, с начала времен и до конца.

  
Наверх
 
IP записан
 
orefkov
1c++ developer
1c++ moderator
Отсутствует


I Love YaBB 2!

Сообщений: 896
Зарегистрирован: 20. Мая 2006
Re: 1sqlite.  Продолжаю обучаться. Наткнулся на одну неприятность...
Ответ #10 - 06. Декабря 2010 :: 06:39
Печать  
LEFT JOIN замени на INNER, и добавь условие
Код
Выбрать все
and Жур.IDDOCDEF=:ВидДокумента." + ТекВид + "
 


и
Док.iddoc
из полей подзапросов убери.
  
Наверх
 
IP записан
 
palpetrovich
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 31
Зарегистрирован: 23. Ноября 2010
Re: 1sqlite.  Продолжаю обучаться. Наткнулся на одну неприятность...
Ответ #11 - 06. Декабря 2010 :: 15:47
Печать  
убрал во внутреннем Док.iddoc, заменил LEFT на INNER и добавил
AND Жур.IDDOCDEF=:ВидДокумента." + ТекВид + "

для одного товара за квартал:
Время выполнения 423 мсек
было:
Время выполнения 4568 мсек

Спасибо Саня Улыбка
  
Наверх
 
IP записан
 
orefkov
1c++ developer
1c++ moderator
Отсутствует


I Love YaBB 2!

Сообщений: 896
Зарегистрирован: 20. Мая 2006
Re: 1sqlite.  Продолжаю обучаться. Наткнулся на одну неприятность...
Ответ #12 - 07. Декабря 2010 :: 06:12
Печать  
palpetrovich писал(а) 06. Декабря 2010 :: 15:47:
для одного товара за квартал:
Время выполнения 423 мсек
было:
Время выполнения 4568 мсек


То-то же Улыбка
1sqlite по определению не может быть медленнее 1С, при грамотном запросе.
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать