(0) большое спасибо, что не бросаете разработку. Интересно конечно как мои классы (ПрямойЗапрос, ПоставщикДанных) поведут себя на новой компоненте. Но у меня уже 7-ки даже не стоит.
Если вдруг ими пользуетесь, скажите, просто интересно.
(1) Должны работать быстрее, хотя бы из-за того что по условию с IN выборка может использовать индекс
Группировка и сортировка в новом движке тоже быстрее, причем значительно быстрее.
Возможно некоторые процедуры ПрямогоЗапроса можно было бы переписать с учетом новых возможностей и было бы еще быстрее, но увы не использую.
Как то напрямую получается проще ;)
Сломаться ничего не должно, но в некоторых случаях могут быть парадоксы!
Я об этом писал на форуме 1с++ http://www.1cpp.ru/forum/YaBB.pl?num=1214205575/789#789 P.S. Текущая сборка на 3.15.1 отлично справилась со всеми вариантами и вышла 100% победителем.
(2) после приключенией с типизацией, таки, перешел на 1.0.2.6, но, все-таки пришлось возвращаться на 1.0.2.3 именно из-за того, что первые прямые писал с классом прямого запроса.
Запросы кривые, но, на том что есть, скорость падала (в сравнении с 1.0.2.3) в разы (было минуты - стало десятки минут, сначала даже подумал что кэш не используется, как локализую на чем затык приключается - покажу примеры)...
Сейчас потихоньку все переписываю на чистый sqlite...
(11) 1.0.2.6 они уже разные бывают... смотри ссылку в (2) Найдешь тормозящий запрос на "прямом" кидай пример. И explain QUERY PLAN к нему. В принципе там сразу видно что не так...
(14) Djelf,
На малых объемах разница не значительна, на больших - критична
1.0.2.3
1.0.2.3
SELECT
Рег.Номенклатура as [Номенклатура $Справочник.Номенклатура],
Рег.НачалоПериода as [День $Дата],
SUM(Рег.КоличествоНачальныйОстаток) as КолвоНачОст,
SUM(Рег.КоличествоКонечныйОстаток) as КолвоКонОст,
SUM(Рег.КоличествоПриход) as КолвоПриход,
SUM(Рег.КоличествоРасход) as КолвоРасход,
SUM(Рег.КоличествоВозврат) as КолвоВозвр,
SUM(Рег.КоличествоНачальныйРезерв) as КолвоРезервНачОст,
SUM(Рег.КоличествоКонечныйРезерв) as КолвоРезервКонОст,
SUM(Рег.КоличествоСписание) as КолСпис
FROM
(
SELECT
Р.Номенклатура as Номенклатура,
Р.НачалоПериода as НачалоПериода,
Р.КоличествоНачальныйОстаток as КоличествоНачальныйОстаток,
Р.КоличествоКонечныйОстаток as КоличествоКонечныйОстаток,
Р.КоличествоПриход as КоличествоПриход,
0 as КоличествоРасход,
0 as КоличествоВозврат,
0 as КоличествоНачальныйРезерв,
0 as КоличествоКонечныйРезерв,
0 as КоличествоСписание
FROM
vt_totalrg_328_769705020 as Р
UNION ALL
SELECT
РегРез.Номенклатура as Номенклатура,
РегРез.НачалоПериода as НачалоПериода,
0 as КоличествоНачальныйОстаток,
0 as КоличествоКонечныйОстаток,
0 as КоличествоПриход,
0 as КоличествоРасход,
0 as КоличествоВозврат,
РегРез.КоличествоНачальныйОстаток as КоличествоНачальныйРезерв,
РегРез.КоличествоКонечныйОстаток as КоличествоКонечныйРезерв,
0 as КоличествоСписание
FROM
vt_totalrg_4480_769705062 as РегРез
UNION ALL
SELECT
РегРасх.Номенклатура as Номенклатура,
РегРасх.Период as НачалоПериода,
0 as КоличествоНачальныйОстаток,
0 as КоличествоКонечныйОстаток,
0 as КоличествоПриход,
РегРасх.КоличествоОборот as КоличествоРасход,
РегРасх.КоличествоВОборот as КоличествоВозврат,
0 as КоличествоНачальныйРезерв,
0 as КоличествоКонечныйРезерв,
0 as КоличествоСписание
FROM
(
SELECT
Период
,Номенклатура
,SUM(КоличествоОборот) AS КоличествоОборот
,SUM(КоличествоВОборот) AS КоличествоВОборот
FROM
(SELECT
docjourn.DATE AS Период
,ra_2351.Номенклатура AS Номенклатура
,CASE WHEN ra_2351.debkred = 0 THEN ra_2351.Количество ELSE -ra_2351.Количество END AS КоличествоОборот
,CASE WHEN ra_2351.debkred = 0 THEN ra_2351.КоличествоВ ELSE -ra_2351.КоличествоВ END AS КоличествоВОборот
FROM
[Журнал] AS docjourn
LEFT JOIN [Регистр.Продажи] AS ra_2351
ON ra_2351.IDDOC = docjourn.IDDOC
WHERE (docjourn.idx_DATE_TIME_IDDOC >= '20161101 0 0 ')
AND (docjourn.idx_DATE_TIME_IDDOC < '20161105 0 0 ')
AND docjourn.ПродажиФр = 1
AND
ra_2351.Номенклатура IN (SELECT Val FROM vt_Номен)
) AS vt_ra_2351
GROUP BY
Период
,Номенклатура
HAVING (SUM(КоличествоОборот) <> 0)
OR (SUM(КоличествоВОборот) <> 0)
) as РегРасх
UNION ALL
SELECT
РегСпис.Номенклатура as Номенклатура,
Жур.DATE as НачалоПериода,
0 as КоличествоНачальныйОстаток,
0 as КоличествоКонечныйОстаток,
0 as КоличествоПриход,
0 as КоличествоРасход,
0 as КоличествоВозврат,
0 as КоличествоНачальныйРезерв,
0 as КоличествоКонечныйРезерв,
РегСпис.КоличествоРасход as КоличествоСписание
FROM
vt_totalrg_328_769705064 as РегСпис
INNER JOIN
[Документ.СписаниеТМЦ] as ДокСпис ON ДокСпис.IDDoc = РегСпис.ТекущийДокумент
LEFT JOIN
[Журнал] as Жур ON Жур.IDDoc = РегСпис.ТекущийДокумент) Рег
GROUP BY
Рег.Номенклатура,
Рег.НачалоПериода
create table x(
[IDDOC] char(9) collate _1C
,[ДокОснование] char(13) collate _1C
,[Склад] char(9) collate _1C
,[Контрагент] char(9) collate _1C
,[Валюта] char(9) collate _1C
,[Курс] numeric(11, 4)
,[Счет] char(23) collate _1C
,[TSP3859] char(3) collate _1C
,[Субконто1] char(23) collate _1C
,[TSP3860] char(3) collate _1C
,[Субконто2] char(23) collate _1C
,[TSP3861] char(3) collate _1C
,[Субконто3] char(23) collate _1C
,[TSP3862] char(3) collate _1C
,[СчетНУ] char(23) collate _1C
,[TSP6144] char(3) collate _1C
,[СубконтоНУ1] char(23) collate _1C
,[TSP6145] char(3) collate _1C
,[СубконтоНУ2] char(23) collate _1C
,[TSP6146] char(3) collate _1C
,[СубконтоНУ3] char(23) collate _1C
,[TSP6147] char(3) collate _1C
,[Сумма] numeric(16, 2)
,Комментарий text collate _1C
, idx_IDDOC char(9) collate _1C
)
create table x(
[IDDOC] char(9) collate _1C
,[LINENO] numeric(4, 0)
,[ACTNO] numeric(6, 0)
,[DEBKRED] numeric(1, 0)
,[Номенклатура] char(9) collate _1C
,[Покупатель] char(9) collate _1C
,[Поставщик] char(9) collate _1C
,[Фирма] char(9) collate _1C
,[Себестоимость] numeric(16, 2)
,[ПродСтоимость] numeric(16, 2)
,[Количество] numeric(16, 5)
,[СебестоимостьВ] numeric(16, 2)
,[ПродСтоимостьВ] numeric(16, 2)
,[КоличествоВ] numeric(16, 5)
, idx_IDDOC_LINENO_ACTNO char(19) collate _1C
)
Подбор индекса для таблицы 1SJOURN:
Ограничения: ACDATETIM[dx_DATE_TIME_IDDOC]>=; ACDATETIM[dx_DATE_TIME_IDDOC]<; RF2351[ПродажиФр]=; IDDOC=;
В кэше не найдено
Выбран индекс IDDOC: IDDOC
Стоимость: 20
Подбор индекса для таблицы 1SJOURN:
Ограничения: ACDATETIM[dx_DATE_TIME_IDDOC]>=; ACDATETIM[dx_DATE_TIME_IDDOC]<; RF2351[ПродажиФр]=;
В кэше не найдено
Выбран индекс ACDATETIM: DTOS(DATE)+TIME+IDDOC
Стоимость: 20
Подбор индекса для таблицы RA2351:
Ограничения: IDDOC=;
В кэше не найдено
Выбран индекс IDLINE: IDDOC+STR(LINENO,4)+STR(ACTNO,6)
Стоимость: 66
Подбор индекса для таблицы DH1790:
Ограничения: IDDOC=;
В кэше не найдено
Выбран индекс ID: IDDOC
Стоимость: 12
Подбор индекса для таблицы DH1790:
Ограничения: IDDOC=;
Найдено в кэше
Выбран индекс ID: IDDOC
Стоимость: 12
Подбор индекса для таблицы 1SJOURN:
Ограничения: IDDOC=;
В кэше не найдено
Выбран индекс IDDOC: IDDOC
Стоимость: 20
Время подготовки запроса: 450 мс, время выполнения запроса: 161 мс.
ПЛАН:
0;0;TABLE vt_totalrg_328_770039760 AS Р
0;0;TABLE vt_totalrg_4480_770039800 AS РегРез
0;0;TABLE Журнал AS docjourn VIRTUAL TABLE INDEX 1:ACDATETIM; 19 !" 0?b 0C?|?*a#dR 0&
1;1;TABLE Регистр.Продажи AS ra_2351 VIRTUAL TABLE INDEX 0:IDLINE; 10 ! 0p nHyd!@4# !
0;0;TABLE vt_Номен
0;0;TABLE vt_totalrg_328_770039802 AS РегСпис
1;1;TABLE Документ.СписаниеТМЦ AS ДокСпис VIRTUAL TABLE INDEX 0:ID; 10 ! 0p nHyd!(?
2;2;TABLE Журнал AS Жур VIRTUAL TABLE INDEX 0:IDDOC; 10 ! 0p nHyd!(?
0;0;TABLE AS Рег
Показать
1.0.2.6 (3.15)
1.0.2.6
SELECT
Рег.Номенклатура as [Номенклатура $Справочник.Номенклатура],
Рег.НачалоПериода as [День $Дата],
SUM(Рег.КоличествоНачальныйОстаток) as КолвоНачОст,
SUM(Рег.КоличествоКонечныйОстаток) as КолвоКонОст,
SUM(Рег.КоличествоПриход) as КолвоПриход,
SUM(Рег.КоличествоРасход) as КолвоРасход,
SUM(Рег.КоличествоВозврат) as КолвоВозвр,
SUM(Рег.КоличествоНачальныйРезерв) as КолвоРезервНачОст,
SUM(Рег.КоличествоКонечныйРезерв) as КолвоРезервКонОст,
SUM(Рег.КоличествоСписание) as КолСпис
FROM
(
SELECT
Р.Номенклатура as Номенклатура,
Р.НачалоПериода as НачалоПериода,
Р.КоличествоНачальныйОстаток as КоличествоНачальныйОстаток,
Р.КоличествоКонечныйОстаток as КоличествоКонечныйОстаток,
Р.КоличествоПриход as КоличествоПриход,
0 as КоличествоРасход,
0 as КоличествоВозврат,
0 as КоличествоНачальныйРезерв,
0 as КоличествоКонечныйРезерв,
0 as КоличествоСписание
FROM
vt_totalrg_328_769799611 as Р
UNION ALL
SELECT
РегРез.Номенклатура as Номенклатура,
РегРез.НачалоПериода as НачалоПериода,
0 as КоличествоНачальныйОстаток,
0 as КоличествоКонечныйОстаток,
0 as КоличествоПриход,
0 as КоличествоРасход,
0 as КоличествоВозврат,
РегРез.КоличествоНачальныйОстаток as КоличествоНачальныйРезерв,
РегРез.КоличествоКонечныйОстаток as КоличествоКонечныйРезерв,
0 as КоличествоСписание
FROM
vt_totalrg_4480_769799692 as РегРез
UNION ALL
SELECT
РегРасх.Номенклатура as Номенклатура,
РегРасх.Период as НачалоПериода,
0 as КоличествоНачальныйОстаток,
0 as КоличествоКонечныйОстаток,
0 as КоличествоПриход,
РегРасх.КоличествоОборот as КоличествоРасход,
РегРасх.КоличествоВОборот as КоличествоВозврат,
0 as КоличествоНачальныйРезерв,
0 as КоличествоКонечныйРезерв,
0 as КоличествоСписание
FROM
(
SELECT
Период
,Номенклатура
,SUM(КоличествоОборот) AS КоличествоОборот
,SUM(КоличествоВОборот) AS КоличествоВОборот
FROM
(SELECT
docjourn.DATE AS Период
,ra_2351.Номенклатура AS Номенклатура
,CASE WHEN ra_2351.debkred = 0 THEN ra_2351.Количество ELSE -ra_2351.Количество END AS КоличествоОборот
,CASE WHEN ra_2351.debkred = 0 THEN ra_2351.КоличествоВ ELSE -ra_2351.КоличествоВ END AS КоличествоВОборот
FROM
[Журнал] AS docjourn
LEFT JOIN [Регистр.Продажи] AS ra_2351
ON ra_2351.IDDOC = docjourn.IDDOC
WHERE (docjourn.idx_DATE_TIME_IDDOC >= '20161101 0 0 ')
AND (docjourn.idx_DATE_TIME_IDDOC < '20161105 0 0 ')
AND docjourn.ПродажиФр = 1
AND
ra_2351.Номенклатура IN (SELECT Val FROM vt_Номен)
) AS vt_ra_2351
GROUP BY
Период
,Номенклатура
HAVING (SUM(КоличествоОборот) <> 0)
OR (SUM(КоличествоВОборот) <> 0)
) as РегРасх
UNION ALL
SELECT
РегСпис.Номенклатура as Номенклатура,
Жур.DATE as НачалоПериода,
0 as КоличествоНачальныйОстаток,
0 as КоличествоКонечныйОстаток,
0 as КоличествоПриход,
0 as КоличествоРасход,
0 as КоличествоВозврат,
0 as КоличествоНачальныйРезерв,
0 as КоличествоКонечныйРезерв,
РегСпис.КоличествоРасход as КоличествоСписание
FROM
vt_totalrg_328_769799694 as РегСпис
INNER JOIN
[Документ.СписаниеТМЦ] as ДокСпис ON ДокСпис.IDDoc = РегСпис.ТекущийДокумент
LEFT JOIN
[Журнал] as Жур ON Жур.IDDoc = РегСпис.ТекущийДокумент) Рег
GROUP BY
Рег.Номенклатура,
Рег.НачалоПериода
create table x(
[IDDOC] char(9) collate _1C not null
,[ДокОснование] char(13) collate _1C not null
,[Склад] char(9) collate _1C not null
,[Контрагент] char(9) collate _1C not null
,[Валюта] char(9) collate _1C not null
,[Курс] numeric(11, 4) not null
,[Счет] char(23) collate _1C not null
,[TSP3859] char(3) collate _1C not null
,[Субконто1] char(23) collate _1C not null
,[TSP3860] char(3) collate _1C not null
,[Субконто2] char(23) collate _1C not null
,[TSP3861] char(3) collate _1C not null
,[Субконто3] char(23) collate _1C not null
,[TSP3862] char(3) collate _1C not null
,[СчетНУ] char(23) collate _1C not null
,[TSP6144] char(3) collate _1C not null
,[СубконтоНУ1] char(23) collate _1C not null
,[TSP6145] char(3) collate _1C not null
,[СубконтоНУ2] char(23) collate _1C not null
,[TSP6146] char(3) collate _1C not null
,[СубконтоНУ3] char(23) collate _1C not null
,[TSP6147] char(3) collate _1C not null
,[Сумма] numeric(16, 2) not null
,Комментарий text collate _1C default null
, idx_IDDOC char(9) collate _1C default null
)
create table x(
[IDDOC] char(9) collate _1C not null
,[LINENO] numeric(4, 0) not null
,[ACTNO] numeric(6, 0) not null
,[DEBKRED] numeric(1, 0) not null
,[Номенклатура] char(9) collate _1C not null
,[Покупатель] char(9) collate _1C not null
,[Поставщик] char(9) collate _1C not null
,[Фирма] char(9) collate _1C not null
,[Себестоимость] numeric(16, 2) not null
,[ПродСтоимость] numeric(16, 2) not null
,[Количество] numeric(16, 5) not null
,[СебестоимостьВ] numeric(16, 2) not null
,[ПродСтоимостьВ] numeric(16, 2) not null
,[КоличествоВ] numeric(16, 5) not null
, idx_IDDOC_LINENO_ACTNO char(19) collate _1C default null
)
szName 1SJOURN
Подбор индекса для таблицы 1SJOURN :
Ограничения: ACDATETIM[dx_DATE_TIME_IDDOC]>=; ACDATETIM[dx_DATE_TIME_IDDOC]<; RF2351[ПродажиФр]=;
Выбран уникальный индекс ACDATETIM: DTOS(DATE)+TIME+IDDOC
Стоимость: 18
szName RA2351
Подбор индекса для таблицы RA2351 :
Ограничения: SP2343[Номенклатура]=; IDDOC=;
Выбран уникальный индекс IDLINE: IDDOC+STR(LINENO,4)+STR(ACTNO,6)
Стоимость: 22
szName DH1790
Подбор индекса для таблицы DH1790 :
Ограничения: IDDOC=;
Выбран уникальный индекс ID: IDDOC
Стоимость: 12
szName DH1790
Подбор индекса для таблицы DH1790 :
Ограничения:
Индекс не выбран.
Стоимость: 1795
szName 1SJOURN
Подбор индекса для таблицы 1SJOURN :
Ограничения: IDDOC=;
Выбран уникальный индекс IDDOC: IDDOC
Стоимость: 20
Время подготовки запроса: 746 мс, время выполнения запроса: 354 мс.
ПЛАН
4;0;0;SCAN TABLE vt_totalrg_328_769282807 AS Р
5;0;0;SCAN TABLE vt_totalrg_4480_769282887 AS РегРез
3;0;0;COMPOUND SUBQUERIES 4 AND 5 (UNION ALL)
6;0;0;SCAN TABLE Журнал AS docjourn VIRTUAL TABLE INDEX 1:ACDATETIM; 19 !" 0?b 0C?|?*a#dR 0&?/=
6;1;1;SCAN TABLE Регистр.Продажи AS ra_2351 VIRTUAL TABLE INDEX 0:IDLINE; 15 ! 0p nHy$40d Q :H RK2B
6;0;0;EXECUTE LIST SUBQUERY 7
7;0;0;SCAN TABLE vt_Номен
6;0;0;EXECUTE LIST SUBQUERY 8
8;0;0;SCAN TABLE vt_Номен
6;0;0;USE TEMP B-TREE FOR GROUP BY
2;0;0;COMPOUND SUBQUERIES 3 AND 6 (UNION ALL)
9;0;0;SCAN TABLE vt_totalrg_328_769282889 AS РегСпис
9;1;1;SCAN TABLE Документ.СписаниеТМЦ AS ДокСпис VIRTUAL TABLE INDEX 0:ID; 10 ! 0p nHyd!0d Q
9;2;2;SCAN TABLE Журнал AS Жур VIRTUAL TABLE INDEX 0:IDDOC; 10 ! 0p nHyd!0d Q
1;0;0;COMPOUND SUBQUERIES 2 AND 9 (UNION ALL)
0;0;0;SCAN SUBQUERY 1 AS Рег
0;0;0;USE TEMP B-TREE FOR GROUP BY
(18) Выглядит ужасно, а выполняется еще хуже ;)
1. Класс в обоих случаях сконструировал один и тот же запрос, что не удивительно.
2. Странно что время подготовки запроса Классом увеличилось почти в 2 раза.
3. План запроса обе версии sqlite сделали примерно одинаковый, 190мс разница небольшая... Повторяемая? За месяц-два тоже ~в 2 раза отличается?
4. У тебя видимо не установлен в регистре флаг "Быстрая обработка движений" из-за этого лишние джойны.
5. Фильтр на Номенклатуру только в одном месте, это так и задумано?
6. Класс не учитывает возможность наложить индекс по Номенклатуре, если на нее установлен отбор. Отбор установлен? Тут можно разогреть запрос очень сильно! При быстрой обработке движений и отбору по номенклатуре сработает составной индекс регистра вида "SP2343,DATE,TIME,IDDOC,LINENO,ACTNO" и это очень сильно ускорит запрос в 3.15. А вот 1.0.2.3 его использовать не сможет вообще!
7. Что внутри vt_totalrg_328_769799611 и т.п. не видать, может там что-то подтормаживает, а не в результирующем запросе.
(18) Непонятненько где и почему тормозит...
Кусок SELECT docjourn.DATE AS Период ,ra_2351.Номенклатура AS Номенклатура в 3.15 в 2 раза быстрее...
Остальные куски должны вести себя так же...
А попробуй ка обернуть запрос в begin rollback, на взаимодействие с 1с это не повлияет. ВыполнятьВТранзакции это для 1с, а не sqlite...
(18) Ага... последний кусок вроде вообще не правильный, возможно он и тормозит
РегСпис.Номенклатура as Номенклатура,
Жур.DATE as НачалоПериода,
FROM
vt_totalrg_328_769799694 as РегСпис
INNER JOIN
[Документ.СписаниеТМЦ] as ДокСпис ON ДокСпис.IDDoc = РегСпис.ТекущийДокумент
LEFT JOIN
[Журнал] as Жур ON Жур.IDDoc = РегСпис.ТекущийДокумент) Рег
Показать
НачалоПериода есть в $РегистрОбороты, ВидДокумента тоже есть т.е. inner join не нужен, а нужно условие в вт на :ВидДокумента.СписаниеТМЦ
Мне не очень нравится что ПрямойЗапрос делает временные таблицы для sqlite, если были бы как вложенные, то движок мог бы их как то их по хитрому развернуть.
(21) Djelf, извиняюсь за "оперативность". ПК под рукой не было...
Запрос кривой - да. Это привет из далекого прошлого. Там всю обработку желательно выкинуть и написать с нуля. Так, конечно, и поступлю, но все разом - проблемно...
Начало периода - только при переодичности отличной от документ, условие на вид документа не ставится, т.к. прямойзапрос его и итоги впихнуть пытается...
Но основные тормоза не там:
1.0.2.3
SELECT
Рег.Номенклатура as [Номенклатура $Справочник.Номенклатура],
Рег.НачалоПериода as [День $Дата],
SUM(Рег.КоличествоНачальныйОстаток) as КолвоНачОст,
SUM(Рег.КоличествоКонечныйОстаток) as КолвоКонОст,
SUM(Рег.КоличествоПриход) as КолвоПриход,
SUM(Рег.КоличествоРасход) as КолвоРасход,
SUM(Рег.КоличествоВозврат) as КолвоВозвр,
SUM(Рег.КоличествоНачальныйРезерв) as КолвоРезервНачОст,
SUM(Рег.КоличествоКонечныйРезерв) as КолвоРезервКонОст,
SUM(Рег.КоличествоСписание) as КолСпис
FROM
(
SELECT
РегРасх.Номенклатура as Номенклатура,
РегРасх.Период as НачалоПериода,
0 as КоличествоНачальныйОстаток,
0 as КоличествоКонечныйОстаток,
0 as КоличествоПриход,
РегРасх.КоличествоОборот as КоличествоРасход,
РегРасх.КоличествоВОборот as КоличествоВозврат,
0 as КоличествоНачальныйРезерв,
0 as КоличествоКонечныйРезерв,
0 as КоличествоСписание
FROM
(
SELECT
Период
,Номенклатура
,SUM(КоличествоОборот) AS КоличествоОборот
,SUM(КоличествоВОборот) AS КоличествоВОборот
FROM
(SELECT
docjourn.DATE AS Период
,ra_2351.Номенклатура AS Номенклатура
,CASE WHEN ra_2351.debkred = 0 THEN ra_2351.Количество ELSE -ra_2351.Количество END AS КоличествоОборот
,CASE WHEN ra_2351.debkred = 0 THEN ra_2351.КоличествоВ ELSE -ra_2351.КоличествоВ END AS КоличествоВОборот
FROM
[Журнал] AS docjourn
LEFT JOIN [Регистр.Продажи] AS ra_2351
ON ra_2351.IDDOC = docjourn.IDDOC
WHERE (docjourn.idx_DATE_TIME_IDDOC >= '20161001 0 0 ')
AND (docjourn.idx_DATE_TIME_IDDOC < '20161101 0 0 ')
AND docjourn.ПродажиФр = 1
AND
ra_2351.Номенклатура IN (SELECT Val FROM vt_Номен)
) AS vt_ra_2351
GROUP BY
Период
,Номенклатура
HAVING (SUM(КоличествоОборот) <> 0)
OR (SUM(КоличествоВОборот) <> 0)
) as РегРасх
) Рег
GROUP BY
Рег.Номенклатура,
Рег.НачалоПериода
create table x(
[IDJOURNAL] char(4) collate _1C
,[IDDOC] char(9) collate _1C
,[IDDOCDEF] char(4) collate _1C
,[APPCODE] numeric(3, 0)
,[DATE] char(8)
,[TIME] char(6) collate _1C
,[DNPREFIX] char(18) collate _1C
,[DOCNO] char(10) collate _1C
,[CLOSED] numeric(1, 0)
,[ISMARK] char(1) collate _1C
,[ACTCNT] char(6) collate _1C
,[VERSTAMP] char(6) collate _1C
,[БанкФр] numeric(1, 0)
,[ЗаказыФр] numeric(1, 0)
,[ЗаказыЗаявкиФр] numeric(1, 0)
,[ЗаявкиФр] numeric(1, 0)
,[КассаФр] numeric(1, 0)
,[КнигаПокупокФр] numeric(1, 0)
,[КнигаПродажФр] numeric(1, 0)
,[ОстаткиТМЦФр] numeric(1, 0)
,[ПартииНаличиеФр] numeric(1, 0)
,[ПартииОтданныеФр] numeric(1, 0)
,[ПодотчетныеЛицаФр] numeric(1, 0)
,[ПокупателиФр] numeric(1, 0)
,[ПоставщикиФр] numeric(1, 0)
,[ПродажиФр] numeric(1, 0)
,[РеализованныйТоварФр] numeric(1, 0)
,[РезервыТМЦФр] numeric(1, 0)
,[Автор] char(9) collate _1C
,[Проект] char(9) collate _1C
,[Фирма] char(9) collate _1C
,[ЮрЛицо] char(9) collate _1C
,[ОсновнаяПоследовательностьПс] numeric(1, 0)
,[КнигаПокупокПс] numeric(1, 0)
,[КнигаПродажПс] numeric(1, 0)
, idx_IDDOC char(9) collate _1C
, idx_DATE_TIME_IDDOC char(23) collate _1C
, idx_DNPREFIX_DOCNO char(28) collate _1C
, idx_IDDOCDEF_DATE_TIME_IDDOC char(27) collate _1C
, idx_IDJOURNAL_DATE_TIME_IDDOC char(27) collate _1C
, idx_Автор_DATE_TIME_IDDOC char(32) collate _1C
, idx_Проект_DATE_TIME_IDDOC char(32) collate _1C
, idx_Фирма_DATE_TIME_IDDOC char(32) collate _1C
, idx_ЮрЛицо_DATE_TIME_IDDOC char(32) collate _1C
, idx_ОсновнаяПоследовательностьПс_DATE_TIME_IDDOC char(24) collate _1C
, idx_КнигаПокупокПс_DATE_TIME_IDDOC char(24) collate _1C
, idx_КнигаПродажПс_DATE_TIME_IDDOC char(24) collate _1C
)
create table x(
[IDDOC] char(9) collate _1C
,[LINENO] numeric(4, 0)
,[ACTNO] numeric(6, 0)
,[DEBKRED] numeric(1, 0)
,[Номенклатура] char(9) collate _1C
,[Покупатель] char(9) collate _1C
,[Поставщик] char(9) collate _1C
,[Фирма] char(9) collate _1C
,[Себестоимость] numeric(16, 2)
,[ПродСтоимость] numeric(16, 2)
,[Количество] numeric(16, 5)
,[СебестоимостьВ] numeric(16, 2)
,[ПродСтоимостьВ] numeric(16, 2)
,[КоличествоВ] numeric(16, 5)
, idx_IDDOC_LINENO_ACTNO char(19) collate _1C
)
Подбор индекса для таблицы 1SJOURN:
Ограничения: ACDATETIM[dx_DATE_TIME_IDDOC]>=; ACDATETIM[dx_DATE_TIME_IDDOC]<; RF2351[ПродажиФр]=; IDDOC=;
В кэше не найдено
Выбран индекс IDDOC: IDDOC
Стоимость: 20
Подбор индекса для таблицы 1SJOURN:
Ограничения: ACDATETIM[dx_DATE_TIME_IDDOC]>=; ACDATETIM[dx_DATE_TIME_IDDOC]<; RF2351[ПродажиФр]=;
В кэше не найдено
Выбран индекс ACDATETIM: DTOS(DATE)+TIME+IDDOC
Стоимость: 20
Подбор индекса для таблицы RA2351:
Ограничения: IDDOC=;
В кэше не найдено
Выбран индекс IDLINE: IDDOC+STR(LINENO,4)+STR(ACTNO,6)
Стоимость: 66
Показать
Время подготовки запроса: 16 мс, время выполнения запроса: 455 мс.
ПЛАН:
0;0;TABLE Журнал AS docjourn VIRTUAL TABLE INDEX 1:ACDATETIM; 19 !" 0?b 0C?|?*a#dR 0& )
1;1;TABLE Регистр.Продажи AS ra_2351 VIRTUAL TABLE INDEX 0:IDLINE; 10 ! 0p nHyd!
0;0;TABLE vt_Номен
0;0;TABLE AS РегРасх
1.0.2.6
SELECT
Рег.Номенклатура as [Номенклатура $Справочник.Номенклатура],
Рег.НачалоПериода as [День $Дата],
SUM(Рег.КоличествоНачальныйОстаток) as КолвоНачОст,
SUM(Рег.КоличествоКонечныйОстаток) as КолвоКонОст,
SUM(Рег.КоличествоПриход) as КолвоПриход,
SUM(Рег.КоличествоРасход) as КолвоРасход,
SUM(Рег.КоличествоВозврат) as КолвоВозвр,
SUM(Рег.КоличествоНачальныйРезерв) as КолвоРезервНачОст,
SUM(Рег.КоличествоКонечныйРезерв) as КолвоРезервКонОст,
SUM(Рег.КоличествоСписание) as КолСпис
FROM
(
SELECT
РегРасх.Номенклатура as Номенклатура,
РегРасх.Период as НачалоПериода,
0 as КоличествоНачальныйОстаток,
0 as КоличествоКонечныйОстаток,
0 as КоличествоПриход,
РегРасх.КоличествоОборот as КоличествоРасход,
РегРасх.КоличествоВОборот as КоличествоВозврат,
0 as КоличествоНачальныйРезерв,
0 as КоличествоКонечныйРезерв,
0 as КоличествоСписание
FROM
(
SELECT
Период
,Номенклатура
,SUM(КоличествоОборот) AS КоличествоОборот
,SUM(КоличествоВОборот) AS КоличествоВОборот
FROM
(SELECT
docjourn.DATE AS Период
,ra_2351.Номенклатура AS Номенклатура
,CASE WHEN ra_2351.debkred = 0 THEN ra_2351.Количество ELSE -ra_2351.Количество END AS КоличествоОборот
,CASE WHEN ra_2351.debkred = 0 THEN ra_2351.КоличествоВ ELSE -ra_2351.КоличествоВ END AS КоличествоВОборот
FROM
[Журнал] AS docjourn
LEFT JOIN [Регистр.Продажи] AS ra_2351
ON ra_2351.IDDOC = docjourn.IDDOC
WHERE (docjourn.idx_DATE_TIME_IDDOC >= '20161001 0 0 ')
AND (docjourn.idx_DATE_TIME_IDDOC < '20161101 0 0 ')
AND docjourn.ПродажиФр = 1
AND
ra_2351.Номенклатура IN (SELECT Val FROM vt_Номен)
) AS vt_ra_2351
GROUP BY
Период
,Номенклатура
HAVING (SUM(КоличествоОборот) <> 0)
OR (SUM(КоличествоВОборот) <> 0)
) as РегРасх
) Рег
GROUP BY
Рег.Номенклатура,
Рег.НачалоПериода
create table x(
[IDJOURNAL] char(4) collate _1C not null
,[IDDOC] char(9) collate _1C not null
,[IDDOCDEF] char(4) collate _1C not null
,[APPCODE] numeric(3, 0) not null
,[DATE] char(8) not null
,[TIME] char(6) collate _1C not null
,[DNPREFIX] char(18) collate _1C not null
,[DOCNO] char(10) collate _1C not null
,[CLOSED] numeric(1, 0) not null
,[ISMARK] char(1) collate _1C not null
,[ACTCNT] char(6) collate _1C not null
,[VERSTAMP] char(6) collate _1C not null
,[БанкФр] numeric(1, 0) not null
,[ЗаказыФр] numeric(1, 0) not null
,[ЗаказыЗаявкиФр] numeric(1, 0) not null
,[ЗаявкиФр] numeric(1, 0) not null
,[КассаФр] numeric(1, 0) not null
,[КнигаПокупокФр] numeric(1, 0) not null
,[КнигаПродажФр] numeric(1, 0) not null
,[ОстаткиТМЦФр] numeric(1, 0) not null
,[ПартииНаличиеФр] numeric(1, 0) not null
,[ПартииОтданныеФр] numeric(1, 0) not null
,[ПодотчетныеЛицаФр] numeric(1, 0) not null
,[ПокупателиФр] numeric(1, 0) not null
,[ПоставщикиФр] numeric(1, 0) not null
,[ПродажиФр] numeric(1, 0) not null
,[РеализованныйТоварФр] numeric(1, 0) not null
,[РезервыТМЦФр] numeric(1, 0) not null
,[Автор] char(9) collate _1C not null
,[Проект] char(9) collate _1C not null
,[Фирма] char(9) collate _1C not null
,[ЮрЛицо] char(9) collate _1C not null
,[ОсновнаяПоследовательностьПс] numeric(1, 0) not null
,[КнигаПокупокПс] numeric(1, 0) not null
,[КнигаПродажПс] numeric(1, 0) not null
, idx_IDDOC char(9) collate _1C default null
, idx_DATE_TIME_IDDOC char(23) collate _1C default null
, idx_DNPREFIX_DOCNO char(28) collate _1C default null
, idx_IDDOCDEF_DATE_TIME_IDDOC char(27) collate _1C default null
, idx_IDJOURNAL_DATE_TIME_IDDOC char(27) collate _1C default null
, idx_Автор_DATE_TIME_IDDOC char(32) collate _1C default null
, idx_Проект_DATE_TIME_IDDOC char(32) collate _1C default null
, idx_Фирма_DATE_TIME_IDDOC char(32) collate _1C default null
, idx_ЮрЛицо_DATE_TIME_IDDOC char(32) collate _1C default null
, idx_ОсновнаяПоследовательностьПс_DATE_TIME_IDDOC char(24) collate _1C default null
, idx_КнигаПокупокПс_DATE_TIME_IDDOC char(24) collate _1C default null
, idx_КнигаПродажПс_DATE_TIME_IDDOC char(24) collate _1C default null
)
create table x(
[IDDOC] char(9) collate _1C not null
,[LINENO] numeric(4, 0) not null
,[ACTNO] numeric(6, 0) not null
,[DEBKRED] numeric(1, 0) not null
,[Номенклатура] char(9) collate _1C not null
,[Покупатель] char(9) collate _1C not null
,[Поставщик] char(9) collate _1C not null
,[Фирма] char(9) collate _1C not null
,[Себестоимость] numeric(16, 2) not null
,[ПродСтоимость] numeric(16, 2) not null
,[Количество] numeric(16, 5) not null
,[СебестоимостьВ] numeric(16, 2) not null
,[ПродСтоимостьВ] numeric(16, 2) not null
,[КоличествоВ] numeric(16, 5) not null
, idx_IDDOC_LINENO_ACTNO char(19) collate _1C default null
)
szName 1SJOURN
Подбор индекса для таблицы 1SJOURN :
Ограничения: ACDATETIM[dx_DATE_TIME_IDDOC]>=; ACDATETIM[dx_DATE_TIME_IDDOC]<; RF2351[ПродажиФр]=;
Выбран уникальный индекс ACDATETIM: DTOS(DATE)+TIME+IDDOC
Стоимость: 18
szName RA2351
Подбор индекса для таблицы RA2351 :
Ограничения: SP2343[Номенклатура]=; IDDOC=;
Выбран уникальный индекс IDLINE: IDDOC+STR(LINENO,4)+STR(ACTNO,6)
Стоимость: 22
Показать
Время подготовки запроса: 15 мс, время выполнения запроса: 2488 мс.
ПЛАН
1;0;0;SCAN TABLE Журнал AS docjourn VIRTUAL TABLE INDEX 1:ACDATETIM; 19 !" 0?b 0C?|?*a#dR 0&`4G
1;1;1;SCAN TABLE Регистр.Продажи AS ra_2351 VIRTUAL TABLE INDEX 0:IDLINE; 15 ! 0p nHy$40d Q
1;0;0;EXECUTE LIST SUBQUERY 2
2;0;0;SCAN TABLE vt_Номен
1;0;0;EXECUTE LIST SUBQUERY 3
3;0;0;SCAN TABLE vt_Номен
1;0;0;USE TEMP B-TREE FOR GROUP BY
0;0;0;SCAN SUBQUERY 1 AS РегРасх
0;0;0;USE TEMP B-TREE FOR GROUP BY
EXPLAIN QUERY PLAN
SELECT
Рег.Номенклатура as [Номенклатура $Справочник.Номенклатура],
Рег.НачалоПериода as [День $Дата],
SUM(Рег.КоличествоНачальныйОстаток) as КолвоНачОст,
SUM(Рег.КоличествоКонечныйОстаток) as КолвоКонОст,
SUM(Рег.КоличествоПриход) as КолвоПриход,
SUM(Рег.КоличествоРасход) as КолвоРасход,
SUM(Рег.КоличествоВозврат) as КолвоВозвр,
SUM(Рег.КоличествоНачальныйРезерв) as КолвоРезервНачОст,
SUM(Рег.КоличествоКонечныйРезерв) as КолвоРезервКонОст,
SUM(Рег.КоличествоСписание) as КолСпис
FROM
(
SELECT
РегРасх.Номенклатура as Номенклатура,
РегРасх.Период as НачалоПериода,
0 as КоличествоНачальныйОстаток,
0 as КоличествоКонечныйОстаток,
0 as КоличествоПриход,
РегРасх.КоличествоОборот as КоличествоРасход,
РегРасх.КоличествоВОборот as КоличествоВозврат,
0 as КоличествоНачальныйРезерв,
0 as КоличествоКонечныйРезерв,
0 as КоличествоСписание
FROM
$РегистрОбороты.Продажи(:ДатаНач,:ДатаКон,День,Номенклатура IN (SELECT Val FROM vt_Номен),(Номенклатура),(Количество,КоличествоВ)) as РегРасх
) Рег
GROUP BY
Рег.Номенклатура,
Рег.НачалоПериода
$РегистрОбороты.Продажи(:НачПериода,:КонПериода,День,+Номенклатура IN (SELECT
IN очень коварная штука. Есть 2 варианта выполнения запроса:
1. читаем исходную таблицу, а потом накладываем фильтр
2. читаем таблицу с условием в IN
Если в IN значений мало то быстрее 2, если много то быстрее 1
В 1.0.2.3 оптимизации в 2 нет, он просто такое не умеет. А движки повыше могут выбрать вариант 2
А тут еще получается что запрос не только к виртуальным таблицам, но и к таблице sqlite. Тестами в sqlite такой вариант не покрыт.
К сожалению прагмой такое поведение не изменить, только при компиляции или плюсом (отключение использования индекса по полю).
(25) И еще хинт нашелся... Измени в ПрямомЗапросе кусок ниже и еще один такой же аналогично.
Без SELECT RAISE(IGNORE); триггер обновляет поле СтрКолонкаИзменений, присваивая его значение самому себе, а оно участвует в индексе, следовательно должен обновится еще и индекс, а это лишняя работа. Это раза в полтора-два ускорит запросы. Можно еще больше ускорить, подавляя запись нулевых значений, но это несколько сложнее...
ТекстЗапроса_Триггер = "create trigger tr_oborot before update of " + СтрКолонкаИзменений + " on " + ИмяВременнойТаблицы + "
|begin
| update " + ИмяВременнойТаблицы + " set
| " + СтрТриггерНачОстаток + "
| where " + ИмяВременнойТаблицы + ".rowid = old.rowid;
|
| update t_ob set
| " + СтрТриггерОборот + "
| where " + СтрЗаменить(СтрЗаменить(СтрУсловияСравненияТабИтогов,ИмяВременнойТаблицы + ".",""),"t_ob","old") + ";
|
| update " + ИмяВременнойТаблицы + " set
| " + СтрТриггерКонОстаток + "
| where " + ИмяВременнойТаблицы + ".rowid = old.rowid;
| SELECT RAISE(IGNORE); -- вот эта строка!!!
|end";
(25) (26) ух ребят, я смотрю вы тут вовсю его (класс) перекапываете, может потом и сборку правильную сделаете для 1С++ форума? Могу заменить и в теме здесь на Инфостарте. Хотя может даже лучше, чтобы автор кто поправит сам и сделал правильную статью, себе sm заработает. Я не против, поскольку сам уже им не занимаюсь.
(27) Да какое там вовсю переписываем... Сделал трассировку ОстаткоИОборотов, наткнулся на триггер, изумился его тормознутости, долго втыкал почему так.
К счастью, решение оказалось очень простое. А то я уже что-то мутное на сте стал придумывать...
В принципе в классе все хорошо, кое что можно на сте перевести, попробовать отказаться от генерации условий типа '20161001 0 0 ' тогда IN заработает ну и все вроде..
Если бы пользовался переписал бы. А так, времени на тестирование не хватит.
Я лучше luajit в sqlite как расширение встрою, а то обычный lua работать то работает, но слишком медленно.
А есть шанс что что-то подобное для восьмерки появится?
Можно-ли в восьмерке работать с какой-то внешней бд, при двух условиях:
1. Не устанавливать никаких драйверов и программ. (с пользовательскими правами на сервере)
2. выполнять в ней SQL запросы.
?
(3) r2d255, Насколько знаю, в 8-ке можно использовать .net сборки, а значит можно использовать готовые либы для разных субд.
Таким образом можно попробовать использовать https://github.com/ret-Phoenix/oscript-sql Там один API подобный запросам 1С для нескольких СУБД.
А... хотя не оно. Оно с сервером работает, а не с файлом. Можно портировать на движок sqlite... Необходимости пока не возникало, а без необходимости стимула нет.
Помню то счастье, когда обладатели dbf-баз могли строить нормальные запросы на основе 1sqlite, а главное использовать ТабличноеПоле!
Спасибо, что не бросил такую вкуснятину.
И Саше Орефкову тоже отельное огромное спасибо.
Доброго всем времени суток !
Прорабатываю такой вариант использования:
1) формируется Таблица Значений
2) "укладывается" в базу
3) запросом вытягиваю значения - это реально быстрее, нежели штатными средствами
Но "затык" - из запроса возвращается таблица с данными во внутреннем представлении - как перевести в нормальное ?
(30) А куда я с клюшек? И вообще, надоело сопли вытирать тем кто сменив место работы с моей конфы перешел на УТ ;)
Да, многого в клюшках уже не хватает, в том числе и вариантов хранения данных, для этого sqlite и использую.
Не совсем же я из ума выжил чтоб засовывать 800к xml`ек в dbf базу...
Подскажите данная компонента подойдет для хранения данных в sqlite? Насколько я вижу все ее используют для запросов к самой 1с базе. Требуется хранить большой объем данных с привязкой к документу в 1с 7.7 .
(32) да. Подойдет.
Разного рода доп данные именно так и храню (н-р. доп информация по номенклатуре со ссылками на картинки), чтобы не править конфигурацию + разного рода конфиги обработок.
Спасибо вам за ваш труд. Я-то думаю, почему у меня соединение трёх таблиц, в каждой по 10000 записей, выполняется минут пятнадцать. Я и так, и эдак пытался, индексы создавал. Думал уже, что возможно придётся осваивать C++, потому что от SQLite отказываться было бы ещё больнее.