Натолкнулся на учень не эффективное получение периодических реквизитов. Использовал вот такой код:
|ВЫБРАТЬ Цены.*
|ИЗ
| $СрезПоследних.Цены(:НаДату
| , (Цена, Валюта, Единица)
| , ($СпрЦен.ПометкаУдаления = 0
| И $СпрЦен.КатегорияЦены В (:ТипЗакупа, :ТипРозница)
| И $СпрЦен.Владелец В (SELECT val FROM #ВыбранныеТовары))
| , ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Цены КАК СпрЦен $nolock
| ПО $СпрЦен.ТекущийЭлемент = ТекущийЭлемент
| ,0
| ) КАК Цены
Он разворачивается в 7 (!!!) вложенных select и исполняется у меня более 12 секунд. (на DBF 65 секунд)
SELECT Цены.*
FROM
(
select
vt_slicelast_SC3772.ТекущийЭлемент
,max(vt_slicelast_SC3772.Валюта) as Валюта
,max(vt_slicelast_SC3772.Единица) as Единица
,max(vt_slicelast_SC3772.Цена) as Цена
from (
select
slicelast_SC3772.objid ТекущийЭлемент
,case when slicelast_SC3772.id = 3776 then LEFT(slicelast_SC3772.VALUE,9) end Валюта
,case when slicelast_SC3772.id = 3863 then LEFT(slicelast_SC3772.VALUE,9) end Единица
,case when slicelast_SC3772.id = 3775 then slicelast_SC3772.VALUE end Цена
from (
select tconst_4.objid, tconst_4.id, tconst_4.date, tconst_4.time, tconst_4.docid, tconst_4.value
from (
select tconst_3.objid, tconst_3.id, tconst_3.date, tconst_3.time, max(tconst_3.docid) docid
from (
select tconst_2.objid, tconst_2.id, tconst_2.date, max(tconst_2.time) time
from (
select tconst_1.objid, tconst_1.id, max(tconst_1.date) date
from _1SCONST tconst_1 (nolock)
LEFT JOIN SC3772 AS СпрЦен (nolock)
ON СпрЦен.ID = tconst_1.objid
where tconst_1.date <= '20120131'
and tconst_1.id in (3776,3863,3775)
and (CASE WHEN СпрЦен.ISMARK = 1 THEN 1 ELSE 0 END = 0
AND СпрЦен.SP3787 IN (' 4 ', ' 3 ')
AND СпрЦен.PARENTEXT IN (SELECT val FROM #ВыбранныеТовары))
group by tconst_1.id, tconst_1.objid) slicelast_SC37721
inner join _1SCONST tconst_2 (nolock)
on slicelast_SC37721.id = tconst_2.id
and slicelast_SC37721.objid = tconst_2.objid
and slicelast_SC37721.date = tconst_2.date
group by tconst_2.id, tconst_2.objid, tconst_2.date) slicelast_SC37722
inner join _1SCONST tconst_3 (nolock)
on slicelast_SC37722.id = tconst_3.id
and slicelast_SC37722.objid = tconst_3.objid
and slicelast_SC37722.date = tconst_3.date
and slicelast_SC37722.time = tconst_3.time
group by tconst_3.id, tconst_3.objid, tconst_3.date, tconst_3.time) slicelast_SC37723
inner join _1SCONST tconst_4 (nolock)
on slicelast_SC37723.id = tconst_4.id
and slicelast_SC37723.objid = tconst_4.objid
and slicelast_SC37723.date = tconst_4.date
and slicelast_SC37723.time = tconst_4.time
and slicelast_SC37723.docid = tconst_4.docid
) slicelast_SC3772
) vt_slicelast_SC3772
group by vt_slicelast_SC3772.ТекущийЭлемент
) AS Цены
При замене на вот такой код прямого запроса 1С++:
|SELECT
| ВыбранныеТовары.val AS [Товар $Справочник.Номенклатура],
| $СпрЦен.КатегорияЦены AS [КатегорияЦены $Справочник.КатегорииЦен],
| $ПоследнееЗначение.Цены.Цена(СпрЦен.ID, :КонДата) AS [Цена $Число],
| $ПоследнееЗначение.Цены.Единица(СпрЦен.ID, :КонДата) AS [Единица $Справочник.Единицы],
| $ПоследнееЗначение.Цены.Валюта(СпрЦен.ID, :КонДата) AS [Валюта $Справочник.Валюты]
|FROM #ВыбранныеТовары AS ВыбранныеТовары
|LEFT JOIN $Справочник.Цены AS СпрЦен (nolock)
| ON ВыбранныеТовары.val = СпрЦен.PARENTEXT
|WHERE
| СпрЦен.ISMARK = 0
| AND $СпрЦен.КатегорияЦены IN (:ТипЗакупа, :ТипРозница)
|ORDER BY
| ВыбранныеТовары.val, $СпрЦен.КатегорияЦены
Разворачивается он в:
SELECT
ВыбранныеТовары.val AS [Товар $Справочник.Номенклатура],
СпрЦен.sp3787 AS [КатегорияЦены $Справочник.КатегорииЦен],
(
select top 1
cast(c3775_vv.value as numeric(14, 2))
from
_1sconst as c3775_vv (nolock)
where
c3775_vv.id = 3775 and
c3775_vv.objid = СпрЦен.ID and
(c3775_vv.date <= '20120131')
order by c3775_vv.date desc, c3775_vv.time desc, c3775_vv.docid desc, c3775_vv.row_id desc
) AS [Цена $Число],
(
select top 1
left(c3863_vv.value, 9)
from
_1sconst as c3863_vv (nolock)
where
c3863_vv.id = 3863 and
c3863_vv.objid = СпрЦен.ID and
(c3863_vv.date <= '20120131')
order by c3863_vv.date desc, c3863_vv.time desc, c3863_vv.docid desc, c3863_vv.row_id desc
) AS [Единица $Справочник.Единицы],
(
select top 1
left(c3776_vv.value, 9)
from
_1sconst as c3776_vv (nolock)
where
c3776_vv.id = 3776 and
c3776_vv.objid = СпрЦен.ID and
(c3776_vv.date <= '20120131')
order by c3776_vv.date desc, c3776_vv.time desc, c3776_vv.docid desc, c3776_vv.row_id desc
) AS [Валюта $Справочник.Валюты]
FROM #ВыбранныеТовары AS ВыбранныеТовары
LEFT JOIN sc3772 AS СпрЦен (nolock)
ON ВыбранныеТовары.val = СпрЦен.PARENTEXT
WHERE
СпрЦен.ISMARK = 0
AND СпрЦен.sp3787 IN (' 4 ', ' 3 ')
ORDER BY
ВыбранныеТовары.val, СпрЦен.sp3787
Запрос выдает все те же данные, (даже больше, т.к. есть явная связь со справочником цен)
Выполняется за 0.1 секунды, т.е более чем в 100 (!!!) раз быстрее.
Надо сказать, что если получать тоже самое обычным 1С-ным циклом по справочнику без запроса, то все равно выходит в 10 раз быстрее (за 1 секунду) чем через $СрезПоследних. (на DBF 1С-ный код работает с той же скоростью, что и быстрый запрос на 1С++ в SQL, т.е. менее чем 0.1 секунды)
Я чего-то не учел или $СрезПоследних на самом деле такой не быстрый?