Оптимизация SQL запроса к БД 1С

коллеги!

Есть ли у кого-нибудь идеи по оптимизации такого запроса:

SELECT H._Fld3165 as PRDID, --- товар
       TRIM(SKALD._Code) as LOCID, --- склад реализации
       RIGHT(CONVERT(nvarchar(35), CONVERT(varbinary, CHEK._Fld6358RRef), 1), 32) AS CUSTID, --- ИД покупателя
       'R' as NKCHANNELID, --- канал сбыта
       CAST(DATETIME2FROMPARTS((DATEPART(YEAR, CHEK._Date_Time) - 2000), DATEPART(MONTH, CHEK._Date_Time),
                               DATEPART(DAY, CHEK._Date_Time), 0, 0, 0, 0, 0) as datetime) as KEYFIGUREDATE, --- дата продажи с обнуленным временем
       TOVAR._Fld6384 as NKACTUALSQTY, --- количество товара
       (SELECT count(_Fld6403RRef)
           FROM Retail2.dbo._Document21
           LEFT JOIN Retail2.dbo._Document21_VT6378 ON _IDRRef = _Document21_IDRRef
           WHERE DATETIME2FROMPARTS(DATEPART(YEAR, _Date_Time), DATEPART(MONTH, _Date_Time),
                 DATEPART(DAY, _Date_Time), 0, 0, 0, 0, 0) = DATETIME2FROMPARTS(DATEPART(YEAR, CHEK._Date_Time), DATEPART(MONTH, CHEK._Date_Time),
                 DATEPART(DAY, CHEK._Date_Time), 0, 0, 0, 0, 0) AND _Fld6358RRef = CHEK._Fld6358RRef
           ) as POSITIONINCHECK --- количество позиций в чеках для каждого клиента на каждый день
FROM Retail2.dbo._Document21 CHEK   --- Документ.ЧекККМ
LEFT OUTER JOIN Retail2.dbo._Document21_VT6378 TOVAR ON CHEK._IDRRef = TOVAR._Document21_IDRRef --- Документ.ЧекККМ.Товары
LEFT OUTER JOIN Retail2.dbo._Reference24 H ON H._IDRRef = TOVAR._Fld6403RRef --- Справочник.ХарактеристикиНоменклатуры
LEFT OUTER JOIN Retail2.dbo._Reference131 SKALD ON SKALD._IDRRef = TOVAR._Fld6394RRef --- Справочник.Склады
INNER JOIN SAP_ibp.dbo.PRODUCT as prod ON prod.PRDID = H._Fld3165 --- фильтр товарной матрицы

Судя по плану запроса, - самое дорогое это подсчет позиций товаров в чеке. Но я так и не смог придумать как его оптимизировать. ОГРОМНОЕ СПАСИБО всем соучастникам!


Ответы (1 шт):

Автор решения: Aziz Umarov

Вынесите

SELECT count(_Fld6403RRef)
FROM Retail2.dbo._Document21
    LEFT JOIN Retail2.dbo._Document21_VT6378 ON _IDRRef = _Document21_IDRRef
WHERE DATETIME2FROMPARTS(DATEPART(YEAR, _Date_Time), DATEPART(MONTH, _Date_Time),
                 DATEPART(DAY, _Date_Time), 0, 0, 0, 0, 0) = DATETIME2FROMPARTS(DATEPART(YEAR, CHEK._Date_Time), DATEPART(MONTH, CHEK._Date_Time),
                 DATEPART(DAY, CHEK._Date_Time), 0, 0, 0, 0, 0) AND _Fld6358RRef = CHEK._Fld6358RRef

в отельный жоин. У вас пересчет counta идет на каждом чеке. Легче подсчитать все чеки сгруппировать по _Fld6358RRef и потом соединить.

→ Ссылка