我正在尝试调整以下查询,该查询对INVENTTABLE有500k IO,我认为这是一个很好的起点。所有联接的复杂性已经打败了我,但我无法绕过一个良好的开端,这会是什么?
提前感谢任何提示。
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
答案 0 :(得分:1)
这只是我还是这个特别的部分有点令人困惑?我先解决这个问题。
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')
您是否可以尝试使用临时表预先确定SALESTAKER ID,然后再加入?在连接条件中使用udf和case语句可能不是最好的主意。
答案 1 :(得分:0)
你想看看可创造性的想法是好的。很明显,结果中没有显示任何字段,也不需要将其作为连接其他两个表的链接。因此,只有在那里才能保证存在适当的可发明记录。这可以在EXISTS条款中完成。
然后检查为什么有两个几乎相似的连接与UNION ALL粘合。所有表都被访问两次。这有必要吗?有一次你想要所有的sl.salesqty&lt; 0并通过stl.subsalesid = st.marimssalesid链接。另一次你想要所有的sl.salesqty&gt; 0并通过stl.subsalesid = st.salesid链接。也许你可以做一个select语句并只访问每个表一次。
结果有一个salestable(st)字段。这是st.DATAAREAID。但实际上这是一个搜索和连接标准,因此您可以用sl.DATAAREAID或甚至文字'adf'替换它。所以表格中没有字段。也许也只是一个存在的东西?
同样,当salestable再次被读为st1时。它不是所选列的一部分,因此它可以转换为EXISTS子句。
这只是第一眼看到的,所以我可能会在这里和那里弄错。它只是给你一些东西开始。