Я пытаюсь настроить следующий запрос, который получил 500k IO против INVENTTABLE, который, как я думал, станет хорошим местом для начала. Сложность всех объединений избила меня, хотя я не смог обернуться вокруг, где хорошее начало было бы с этим?Настройка SQL-запроса
Заранее благодарим за любые советы.
SET STATISTICS IO ON
DECLARE
@paramCompany varchar(3),
@paramCreatedBy varchar(8000),
@paramCustomer varchar(100),
@paramBlanketId varchar(20)
SET @paramCompany = 'adf'
SET @paramCreatedBy = 'All'
SET @paramCustomer = NULL
SET @paramBlanketId = NULL
SELECT
un.MAINSALESID,
un.DATAAREAID,
Sum(un.Quantity) as 'Quantity',
Sum(un.SalesValue) as 'SalesValue'
INTO #desprel
FROM
(SELECT
stl.MAINSALESID,
st.DATAAREAID,
sl.SALESQTY as 'Quantity',
sl.SALESQTY * sl.SALESPRICE as 'SalesValue'
FROM
DynamicsV5Realtime.dbo.SALESTABLE st
INNER JOIN
DynamicsV5Realtime.dbo.SALESLINE sl
ON
sl.SALESID = st.SALESID
and sl.DATAAREAID = st.DATAAREAID
INNER JOIN
DynamicsV5Realtime.dbo.INVENTTABLE it
ON
it.ITEMID = sl.ITEMID
and it.DATAAREAID = sl.DATAAREAID
INNER JOIN
DynamicsV5Realtime.dbo.SALESTABLELINKS stl
ON
stl.SUBSALESID = st.SALESID
and stl.DATAAREAID = st.DATAAREAID
INNER JOIN
DynamicsV5Realtime.dbo.SALESTABLE st1
ON
st1.SALESID = stl.MAINSALESID
and st1.SALESTYPE = 5
--to get Order created by
inner JOIN
--TR
vw_R000_EmployeeList pm
ON
--st1.SALESTAKER = pm.emplid
CASE WHEN st1.SALESTAKER = 'balla' THEN 'gende' ELSE st1.SALESTAKER END = pm.emplid
and (pm.[NAME] in (SELECT * FROM udf_MultiValueParameterHandlingString(@paramCreatedBy)) or @paramCreatedBy = 'All')
WHERE
st.DATAAREAID = 'adf'
and st.SALESTYPE = 3 -- Release Order
and st.SALESSTATUS in (2,3)
and sl.SALESSTATUS <> 4
and it.ITEMGROUPID <> 'G0022A'
and sl.SALESQTY > 0
and st1.CUSTACCOUNT = IsNull(@paramCustomer,st1.CUSTACCOUNT)
and st1.SALESID = IsNull(@paramBlanketId,st1.SALESID)
UNION ALL
SELECT
stl.MAINSALESID,
st.DATAAREAID,
sl.SALESQTY as 'Quantity',
sl.SALESQTY * sl.SALESPRICE as 'SalesValue'
FROM
DynamicsV5Realtime.dbo.SALESTABLE st
INNER JOIN
DynamicsV5Realtime.dbo.SALESLINE sl
ON
sl.SALESID = st.SALESID
and sl.DATAAREAID = st.DATAAREAID
INNER JOIN
DynamicsV5Realtime.dbo.INVENTTABLE it
ON
it.ITEMID = sl.ITEMID
and it.DATAAREAID = sl.DATAAREAID
INNER JOIN
DynamicsV5Realtime.dbo.SALESTABLELINKS stl
ON
stl.SUBSALESID = st.MARIMSSALESID
and stl.DATAAREAID = st.DATAAREAID
INNER JOIN
DynamicsV5Realtime.dbo.SALESTABLE st1
ON
st1.SALESID = stl.MAINSALESID
and st1.SALESTYPE = 5
--to get Order created by
inner JOIN
--TR
vw_R000_EmployeeList pm
ON
--st1.SALESTAKER = pm.emplid
CASE WHEN st1.SALESTAKER = 'balla' THEN 'gende' ELSE st1.SALESTAKER END = pm.emplid
and (pm.[NAME] in (SELECT * FROM udf_MultiValueParameterHandlingString(@paramCreatedBy)) or @paramCreatedBy = 'All')
WHERE
st.DATAAREAID = 'adf'
and st.SALESTYPE = 3 -- Release Order
and st.SALESSTATUS in (2,3)
and sl.SALESSTATUS <> 4
and it.ITEMGROUPID <> 'G0022A'
and sl.SALESQTY < 0
and st1.CUSTACCOUNT = IsNull(@paramCustomer,st1.CUSTACCOUNT)
and st1.SALESID = IsNull(@paramBlanketId,st1.SALESID)
) un
GROUP BY
un.MAINSALESID,
un.DATAAREAID
Возможно, вы захотите отметить как SQL Server, поскольку настройка может быть довольно специфичной для РСУБД. –
Да. Предполагая, что это IS Sql Server, запустите запрос в SSMS и скажите ему, чтобы он создал план запроса. Что я делаю, тогда он ищет операцию с наивысшим% и пытается ее оптимизировать. Также SSMS иногда предлагает новые индексы, которые помогут: их применение, как правило, хорошо! –
Да, я смотрю план выполнения, и один из самых больших запросов индекса относится к таблице DIRPARTYCOMMUNICATIONRELA - это должна быть какая-то внутренняя рабочая таблица, поэтому не знаете, как я могу ее индексировать. Я надеялся на какую-то помощь в том, как переписать запрос, чтобы снизить общий объем IO, поэтому я могу применить эту технику в другом месте. – Tom