Переключение на Главную Страницу Страницы: 1 ... 50 51 [52] 53 54 ... 79 ОтправитьПечать
Очень популярная тема (более 25 ответов) 1sqlite (число прочтений - 456714 )
Djelf
God Member
*****
Отсутствует


Ubuntu + wine@etersoft
+ 1C 7.7

Сообщений: 631
Местоположение: Питер
Зарегистрирован: 02. Ноября 2007
Пол: Мужской
Re: 1sqlite
Ответ #765 - 01. Марта 2015 :: 10:10
Печать  
Asakra писал(а) 28. Февраля 2015 :: 16:47:
точный запрос прилагать не буду. типо того:

Давай все таки точный запрос... ну никак повторить не удается  Злой

Надо найти причину. 3.7.17 раз в 50 на таком запросе быстрее - овчинка выделки то стоит.
« Последняя редакция: 01. Марта 2015 :: 12:23 - Djelf »  
Наверх
www  
IP записан
 
Asakra
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 83
Местоположение: Иркутск
Зарегистрирован: 28. Августа 2012
Пол: Мужской
Re: 1sqlite
Ответ #766 - 06. Марта 2015 :: 02:16
Печать  
вот
Код
Выбрать все
CREATE TABLE vt_ДанныеОтчета AS

SELECT
	Рег.Должность		AS Должность,
	Рег.Сотрудник		AS Сотрудник,
	Рег.Контрагент		AS Контрагент,
	Рег.ВидСтавки		AS ВидСтавки,
	Рег.Ставка			AS Ставка,
	Рег.ТекущийДокумент	AS Документ,
	Рег.ВидДокумента	AS ВидДокумента,
	Рег.СуммаЗарплатыОстатки	AS НачОстСуммаЗП,
	Рег.СуммаЗарплатыПриход		AS ПриходСуммаЗП,
	Рег.СуммаЗарплатыРасход		AS ДвРасходСуммаЗП,
	Рег.СуммаПродажиОстаток		AS НачОстСумПродажи,
	Рег.СуммаПродажиПриход		AS ПриходСумПродажи,
	Рег.СуммаПродажиРасход		AS ДвРасходСумПродажи,
	Рег.СуммаПоступлениеДенег	AS ПоступлениеДенег,
	Рег.СуммаЗарплатыОбороты	AS СуммаЗарплатыОбороты,
	Рег.СуммаПродажиОбороты		AS СуммаПродажиОбороты,
	Рег.ПозицияДокумента		AS ПозицияДокумента,
	Рег.КодОперации				AS КодОперации

FROM
	(SELECT
		CASE
			WHEN Остатки.ТОПМенеджер = '     0   '
				THEN 'Менеджеры'
			ELSE 'ТОР-Менеджеры'
		END AS Должность,

		CASE
			WHEN Остатки.ТОПМенеджер = '     0   '
				THEN Остатки.Сотрудник
			ELSE Остатки.ТОПМенеджер
		END AS Сотрудник,

		Остатки.Контрагент,
		Остатки.ВидСтавки,
		Остатки.Ставка,
		'     0   ' AS ТекущийДокумент,
		'    ' AS ВидДокумента,
		Остатки.СуммаЗарплатыОстаток AS СуммаЗарплатыОстатки,
		0 AS СуммаЗарплатыПриход,
		0 AS СуммаЗарплатыРасход,
		Остатки.СуммаПродажиОстаток,
		0 AS СуммаПродажиПриход,
		0 AS СуммаПродажиРасход,
		0 AS СуммаПоступлениеДенег,
		0 AS СуммаЗарплатыОбороты,
		0 AS СуммаПродажиОбороты,
		'' AS ПозицияДокумента,
		'     0   ' AS КодОперации

	FROM
		(
	SELECT
		Сотрудник
		,Контрагент
		,ТОПМенеджер
		,ВидСтавки
		,Ставка
		,SUM(СуммаЗарплатыОстаток) AS СуммаЗарплатыОстаток
		,SUM(СуммаПродажиОстаток) AS СуммаПродажиОстаток

	FROM
		(SELECT
			rg_9713.Сотрудник AS Сотрудник
			,rg_9713.Контрагент AS Контрагент
			,rg_9713.ТОПМенеджер AS ТОПМенеджер
			,rg_9713.ВидСтавки AS ВидСтавки
			,rg_9713.Ставка AS Ставка
			,rg_9713.СуммаЗарплаты AS СуммаЗарплатыОстаток
			,rg_9713.СуммаПродажи AS СуммаПродажиОстаток

		FROM
			[РегистрИтоги.ЗарплатаОтПродаж] AS rg_9713
		WHERE
			rg_9713.PERIOD = '20150101'
		AND
			(rg_9713.Сотрудник = '     V   ' AND  rg_9713.Контрагент IN (SELECT val FROM vt_СписокКонтрагент))
		) AS vt_ra_9713
	GROUP BY
		Сотрудник
		,Контрагент
		,ТОПМенеджер
		,ВидСтавки
		,Ставка
	HAVING (SUM(СуммаЗарплатыОстаток) <> 0)
	OR (SUM(СуммаПродажиОстаток) <> 0)

) AS Остатки

	UNION ALL

	SELECT
		CASE
			WHEN Обороты.ТОПМенеджер = '     0   '
				THEN 'Менеджеры'
			ELSE 'ТОР-Менеджеры'
		END,

		CASE
			WHEN Обороты.ТОПМенеджер = '     0   '
				THEN Обороты.Сотрудник
			ELSE Обороты.ТОПМенеджер
		END,

		Обороты.Контрагент,
		Обороты.ВидСтавки,
		Обороты.Ставка,
		Обороты.ТекущийДокумент,
		Обороты.ВидДокумента,
		0,
		Обороты.СуммаЗарплатыПриход,
		Обороты.СуммаЗарплатыРасход,
		0,
		Обороты.СуммаПродажиПриход,
		Обороты.СуммаПродажиРасход,

		CASE
			WHEN ROUND(Обороты.СуммаПродажиРасход, 2) > 0 AND Обороты.КодОперации = '   1MN   '
				THEN Обороты.СуммаПродажиРасход
			ELSE 0
		END,

		Обороты.СуммаЗарплатыПриход - Обороты.СуммаЗарплатыРасход,
		Обороты.СуммаПродажиПриход - Обороты.СуммаПродажиРасход,
		Обороты.ПозицияДокумента,
		Обороты.КодОперации

	FROM
		(
	SELECT
		ТекущийДокумент
		,ВидДокумента
		,ПозицияДокумента
		,Сотрудник
		,Контрагент
		,ТОПМенеджер
		,ВидСтавки
		,Ставка
		,КодОперации
		,SUM(СуммаЗарплатыПриход) AS СуммаЗарплатыПриход
		,SUM(СуммаЗарплатыРасход) AS СуммаЗарплатыРасход
		,SUM(СуммаЗарплатыОборот) AS СуммаЗарплатыОборот
		,SUM(СуммаПродажиПриход) AS СуммаПродажиПриход
		,SUM(СуммаПродажиРасход) AS СуммаПродажиРасход
		,SUM(СуммаПродажиОборот) AS СуммаПродажиОборот

	FROM
		(SELECT
			ra_9713.IDDOC AS ТекущийДокумент
			,ra_9713.IDDOCDEF AS ВидДокумента
			,SUBSTR(ra_9713.idx_DATE_TIME_IDDOC_LINENO_ACTNO,1,23) AS ПозицияДокумента
			,ra_9713.Сотрудник AS Сотрудник
			,ra_9713.Контрагент AS Контрагент
			,ra_9713.ТОПМенеджер AS ТОПМенеджер
			,ra_9713.ВидСтавки AS ВидСтавки
			,ra_9713.Ставка AS Ставка
			,ra_9713.КодОперации AS КодОперации
			,CASE WHEN ra_9713.debkred = 0 THEN ra_9713.СуммаЗарплаты ELSE 0 END AS СуммаЗарплатыПриход
			,CASE WHEN ra_9713.debkred = 1 THEN ra_9713.СуммаЗарплаты ELSE 0 END AS СуммаЗарплатыРасход
			,CASE WHEN ra_9713.debkred = 0 THEN ra_9713.СуммаЗарплаты ELSE -ra_9713.СуммаЗарплаты END AS СуммаЗарплатыОборот
			,CASE WHEN ra_9713.debkred = 0 THEN ra_9713.СуммаПродажи ELSE 0 END AS СуммаПродажиПриход
			,CASE WHEN ra_9713.debkred = 1 THEN ra_9713.СуммаПродажи ELSE 0 END AS СуммаПродажиРасход
			,CASE WHEN ra_9713.debkred = 0 THEN ra_9713.СуммаПродажи ELSE -ra_9713.СуммаПродажи END AS СуммаПродажиОборот

		FROM
			[Регистр.ЗарплатаОтПродаж] AS ra_9713
		WHERE (ra_9713.idx_DATE_TIME_IDDOC_LINENO_ACTNO >= '20150201     0     0   ')
		AND (ra_9713.idx_DATE_TIME_IDDOC_LINENO_ACTNO < '20150301     0     0   ')
		AND
			(ra_9713.Сотрудник = '     V   ' AND  ra_9713.Контрагент IN (SELECT val FROM vt_СписокКонтрагент))
		) AS vt_ra_9713
	GROUP BY
		ТекущийДокумент
		,ВидДокумента
		,ПозицияДокумента
		,Сотрудник
		,Контрагент
		,ТОПМенеджер
		,ВидСтавки
		,Ставка
		,КодОперации
	HAVING (SUM(СуммаЗарплатыПриход) <> 0)
	OR (SUM(СуммаЗарплатыРасход) <> 0)
	OR (SUM(СуммаЗарплатыОборот) <> 0)
	OR (SUM(СуммаПродажиПриход) <> 0)
	OR (SUM(СуммаПродажиРасход) <> 0)
	OR (SUM(СуммаПродажиОборот) <> 0)

) AS Обороты
	) AS Рег
 

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


1C++ rocks!

Сообщений: 83
Местоположение: Иркутск
Зарегистрирован: 28. Августа 2012
Пол: Мужской
Re: 1sqlite
Ответ #767 - 06. Марта 2015 :: 02:18
Печать  
Djelf писал(а) 01. Марта 2015 :: 10:10:
3.7.17 раз в 50 на таком запросе быстрее


чет я не ощутил разницы
  
Наверх
 
IP записан
 
Asakra
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 83
Местоположение: Иркутск
Зарегистрирован: 28. Августа 2012
Пол: Мужской
Re: 1sqlite
Ответ #768 - 06. Марта 2015 :: 02:24
Печать  
проверял после выполнения этого запроса так:

Код
Выбрать все
SELECT * FROM vt_ДанныеОтчета 



Код
Выбрать все
Результат.ВыбратьСтроку() 

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



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: 1sqlite
Ответ #769 - 06. Марта 2015 :: 06:25
Печать  
Код
Выбрать все
CASE WHEN ra_9713.debkred = 0 THEN ra_9713.СуммаЗарплаты ELSE 0 END AS СуммаЗарплатыПриход 



case не нужен в таких местах, проще писать

Код
Выбрать все
СуммаЗарплаты*(1-debkred) as СуммаЗарплатыПриход 


и т.д
  
Наверх
 
IP записан
 
Djelf
God Member
*****
Отсутствует


Ubuntu + wine@etersoft
+ 1C 7.7

Сообщений: 631
Местоположение: Питер
Зарегистрирован: 02. Ноября 2007
Пол: Мужской
Re: 1sqlite
Ответ #770 - 06. Марта 2015 :: 08:54
Печать  
Asakra писал(а) 06. Марта 2015 :: 02:18:
Djelf писал(а) 01. Марта 2015 :: 10:10:
3.7.17 раз в 50 на таком запросе быстрее


чет я не ощутил разницы


Запрос то большой. 1500мс и 37мс разницы на IN съедаются остальными операциями.

А в какой именно строке запроса IN глючит?
  
Наверх
www  
IP записан
 
Asakra
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 83
Местоположение: Иркутск
Зарегистрирован: 28. Августа 2012
Пол: Мужской
Re: 1sqlite
Ответ #771 - 06. Марта 2015 :: 09:12
Печать  
Djelf писал(а) 06. Марта 2015 :: 08:54:
А в какой именно строке запроса IN глючит?


я ж примерчик бросал Улыбка
Код
Выбрать все
ra_9713.Контрагент IN (SELECT val FROM vt_СписокКонтрагент) 

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


1C++ rocks!

Сообщений: 83
Местоположение: Иркутск
Зарегистрирован: 28. Августа 2012
Пол: Мужской
Re: 1sqlite
Ответ #772 - 06. Марта 2015 :: 09:13
Печать  
на оборотах.
  
Наверх
 
IP записан
 
Asakra
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 83
Местоположение: Иркутск
Зарегистрирован: 28. Августа 2012
Пол: Мужской
Re: 1sqlite
Ответ #773 - 06. Марта 2015 :: 09:22
Печать  
Eprst писал(а) 06. Марта 2015 :: 06:25:
case не нужен в таких местах


я в курсе. это класс "Прямой запрос". остатки ломы самому писать  Круглые глаза
если есть проблемы с производительностью, пишу сам...
  
Наверх
 
IP записан
 
Asakra
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 83
Местоположение: Иркутск
Зарегистрирован: 28. Августа 2012
Пол: Мужской
Re: 1sqlite
Ответ #774 - 06. Марта 2015 :: 09:27
Печать  
Djelf писал(а) 06. Марта 2015 :: 08:54:
1500мс и 37мс разницы на IN съедаются остальными операциями.


ну не знаю. этот запрос <200 мс выполняется
может это если табличка в IN большая!?
  
Наверх
 
IP записан
 
Djelf
God Member
*****
Отсутствует


Ubuntu + wine@etersoft
+ 1C 7.7

Сообщений: 631
Местоположение: Питер
Зарегистрирован: 02. Ноября 2007
Пол: Мужской
Re: 1sqlite
Ответ #775 - 06. Марта 2015 :: 09:50
Печать  
Asakra писал(а) 06. Марта 2015 :: 09:27:
Djelf писал(а) 06. Марта 2015 :: 08:54:
1500мс и 37мс разницы на IN съедаются остальными операциями.


ну не знаю. этот запрос <200 мс выполняется
может это если табличка в IN большая!?


Ну я без фильтра по дате проверял. Тогда существенная разница получается. Если меньше 200мс то и так хорошо. А отбор в регистре по Контрагенту то есть?

На оборотах... ага... Уже ближе к телу. А если отдельно подзапрос проверить что будет? Сузить поиски.

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


1C++ rocks!

Сообщений: 83
Местоположение: Иркутск
Зарегистрирован: 28. Августа 2012
Пол: Мужской
Re: 1sqlite
Ответ #776 - 06. Марта 2015 :: 10:02
Печать  
Djelf писал(а) 06. Марта 2015 :: 09:50:
А отбор в регистре по Контрагенту то есть?

На оборотах... ага... Уже ближе к телу. А если отдельно подзапрос проверить что будет? Сузить поиски.


отборов нет, не было необходимости.

я как бы сразу писал, что в оборотах Улыбка
щас попробую
  
Наверх
 
IP записан
 
Djelf
God Member
*****
Отсутствует


Ubuntu + wine@etersoft
+ 1C 7.7

Сообщений: 631
Местоположение: Питер
Зарегистрирован: 02. Ноября 2007
Пол: Мужской
Re: 1sqlite
Ответ #777 - 06. Марта 2015 :: 10:17
Печать  
Asakra писал(а) 06. Марта 2015 :: 10:02:
[quote author=Djelf link=1214205575/765#775 date=1425635405]
щас попробую


Стопэ! Поймал баг! Пошел курить почему так...

upd:
Вкурил...
Вот и минимальный запрос приводящий к этому багу с sqlite 3.7.15-3.7.17
Код
Выбрать все
SELECT
    iddoc,
    Номенклатура
FROM [Регистр.ОстаткиТМЦ]
WHERE
    (idx_DATE_TIME_IDDOC_LINENO_ACTNO >= '20140101     0     0   ')
    AND (idx_DATE_TIME_IDDOC_LINENO_ACTNO < '20141201     0     0   ')
    AND Номенклатура in (SELECT val FROM vt)
GROUP BY
    iddoc,
    Номенклатура
 


sqlite 3.7.17, зараза такая, использует в этом запросе индекс по idx_DATE_TIME_IDDOC_LINENO_ACTNO, а потом похоже по нему же и сворачивает, но в каком то обрезанном варианте  Злой
ну тут еще планировщик 1sqlite подкачал, т.к. не вычислил что есть более подходящий индекс: Номенклатура,DATE,TIME,IDDOC,LINENO,ACTNO

Кстати, если бы в запросе было указано DATE BETWEN вместо то ошибки бы не было, но зато попало бы в индекс Номенклатура,DATE,TIME,IDDOC,LINENO,ACTNO что на 3.7.17 раз в 10 быстрее.

upd2:
Кажется нашел где отключить эту фигню (backport 1й строчки из 3.7.14)  Круглые глаза
Фактически отключаются некоторые оптимизации внутри sqlite по IN (что и сбивало планировщик), при этом план запросов становятся более похож на оригинальные версии 1sqlite.
Запросы по подбору индекса по IN в 3.7.17 все равно поступают в 1sqlite, в отличие от оригинальных версий, что позволяет 1sqlite предложить в данном запросе (если условие будет на DATE BETWEN) индекс Номенклатура,DATE,TIME,IDDOC,LINENO,ACTNO, что в оригинальной версии невозможно.
« Последняя редакция: 06. Марта 2015 :: 16:32 - Djelf »  

1sqlite_3_7_17_bf2_001.zip ( 307 KB | Загрузки )
Наверх
www  
IP записан
 
Asakra
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 83
Местоположение: Иркутск
Зарегистрирован: 28. Августа 2012
Пол: Мужской
Re: 1sqlite
Ответ #778 - 08. Марта 2015 :: 05:13
Печать  
Djelf писал(а) 06. Марта 2015 :: 10:17:
если условие будет на DATE BETWEN


т.е. если нужны остатки на позицию документа, то лучше писать date between :начДата and :конДата and time <:время and ididoc < :док
или это касается только использования IN по измерению с отбором?
  
Наверх
 
IP записан
 
Djelf
God Member
*****
Отсутствует


Ubuntu + wine@etersoft
+ 1C 7.7

Сообщений: 631
Местоположение: Питер
Зарегистрирован: 02. Ноября 2007
Пол: Мужской
Re: 1sqlite
Ответ #779 - 08. Марта 2015 :: 06:59
Печать  
Asakra писал(а) 08. Марта 2015 :: 05:13:
Djelf писал(а) 06. Марта 2015 :: 10:17:
если условие будет на DATE BETWEN


т.е. если нужны остатки на позицию документа, то лучше писать date between :начДата and :конДата and time <:время and ididoc < :док
или это касается только использования IN по измерению с отбором?


IN тут ни при чем, он рассматривается планировщиком как = и вложенный подзапрос.
вот индексы таблицы движений
Код
Выбрать все
I=IDLINE	    IDDOC,LINENO,ACTNO
I=DATETIME   DATE,TIME,IDDOC,LINENO,ACTNO
I=VIA408       SP408,DATE,TIME,IDDOC,LINENO,ACTNO
 


где SP408 - Номенклатура

Есть 2 ограничения на таблицу DATE,TIME,IDDOC и SP408

Если указать ограничение по составному полю idx_DATE_TIME_IDDOC_LINENO_ACTNO и SP408 то будет выбран индекс DATETIME, а если указывать DATE,TIME,IDDOC,SP408 раздельно, то должен быть выбран индекс VIA408
Ну а эффективность выборки зависит от базы. У меня VIA408 в этом запросе быстрее чем DATETIME, но в какой то ситуации может быть и наоборот.
EXPLAIN QUERY PLAN в помощь...
  
Наверх
www  
IP записан
 
Переключение на Главную Страницу Страницы: 1 ... 50 51 [52] 53 54 ... 79
ОтправитьПечать