SQL WHERE 子句性能问题 AX2012R3
SQL WHERE clause perfromance issue AX2012R3
我正在尝试优化查询。
请注意,我正在使用 Microsoft Dynamics AX 并将此查询追溯到 SQL。
除了索引提示之外的查询是由 Dynamics 生成的,我想知道我是否必须在 AX 中重写整个语句,或者我是否可以通过简单地向索引添加更改来解决这个问题。
查询如下:
SELECT T1.PARTITION, T1.DECIMALPRECISION, T1.RECID, T1.RECVERSION, T1.SYMBOL, T1.SYSTEMOFUNITS, T1.UNITOFMEASURECLASS
FROM UNITOFMEASURE AS T1 WITH(INDEX(I_4436SYMBOLIDX))
WHERE T1.PARTITION = 5637144576 AND EXISTS
(SELECT 'x' AS Expr1
FROM UNITOFMEASURECONVERSION AS T2 WITH(INDEX(I_4438CONVERSIONIDX))
WHERE (T2.PARTITION = 5637144576 )
AND (T2.PRODUCT = 5637297578 OR T2.PRODUCT = 0)
AND (T1.RECID = T2.FROMUNITOFMEASURE)
AND (T2.TOUNITOFMEASURE = 0) OR
(T2.PARTITION = 5637144576) AND (T2.PRODUCT = 5637297578 OR
T2.PRODUCT = 0) AND (T1.RECID = T2.TOUNITOFMEASURE) AND (T2.FROMUNITOFMEASURE = 0))
此查询returns以下执行计划:
可以看到它读取了 5 342544 条记录。相应的表包含 1342 和 3984 条记录。
如果我删除第一个 T1.PARTITION = 5637144576
where 子句,查询将按应有的方式执行。
这是更新后的查询:
SELECT T1.PARTITION, T1.DECIMALPRECISION, T1.RECID, T1.RECVERSION, T1.SYMBOL, T1.SYSTEMOFUNITS, T1.UNITOFMEASURECLASS
FROM UNITOFMEASURE AS T1 WITH(INDEX(I_4436SYMBOLIDX))
WHERE EXISTS
(SELECT 'x' AS Expr1
FROM UNITOFMEASURECONVERSION AS T2 WITH(INDEX(I_4438CONVERSIONIDX))
WHERE (T2.PARTITION = 5637144576 )
AND (T2.PRODUCT = 5637297578 OR T2.PRODUCT = 0)
AND (T1.RECID = T2.FROMUNITOFMEASURE)
AND (T2.TOUNITOFMEASURE = 0) OR
(T2.PARTITION = 5637144576) AND (T2.PRODUCT = 5637297578 OR
T2.PRODUCT = 0) AND (T1.RECID = T2.TOUNITOFMEASURE) AND (T2.FROMUNITOFMEASURE = 0))
现在它使用以下执行计划:
以下是有关所用索引的更多信息:
我可以通过更改索引来优化性能吗?
或者我是否必须通过在 Dynamics AX 2012 中自己构建查询来重写功能。
提前致谢。
您的查询一团糟。 EXISTS
中的 OR
会降低性能。因此,使用多个 EXISTS
子句。我认为是这样的逻辑:
SELECT . . .
FROM UNITOFMEASURE AS T1
WHERE T1.PARTITION = 5637144576 AND
(EXISTS (SELECT 1
FROM UNITOFMEASURECONVERSION T2
WHERE T2.FROMUNITOFMEASURE = T1.RECID AND
T2.PARTITION = 5637144576 AND
T2.PRODUCT IN (5637297578, 0) AND
T2.TOUNITOFMEASURE = 0
) OR
EXISTS (SELECT 1
FROM UNITOFMEASURECONVERSION T2
WHERE T2.TOUNITOFMEASURE = T1.RECID AND
T2.PARTITION = 5637144576 AND
T2.PRODUCT IN (5637297578, 0) AND
T2.FROMUNITOFMEASURE = 0
)
);
那么您需要索引:
UNITOFMEASURE(PARTITION, RECID)
UNITOFMEASURECONVERSION(RECID, PARTITION, PRODUCT, FROMUNITOFMEASURE, TOUNITOFMEASURE)
我认为第二个索引对两个子查询都有用。
实际上,如果我正确解释查询,它可以写成:
SELECT . . .
FROM UNITOFMEASURE AS T1
WHERE T1.PARTITION = 5637144576 AND
EXISTS (SELECT 1
FROM UNITOFMEASURECONVERSION T2
WHERE T2.FROMUNITOFMEASURE = T1.RECID AND
T2.PARTITION = 5637144576 AND
T2.PRODUCT IN (5637297578, 0) AND
(T2.TOUNITOFMEASURE = 0 OR T2.FROMUNITOFMEASURE = 0)
);
并且上述索引应该有效。
我正在尝试优化查询。 请注意,我正在使用 Microsoft Dynamics AX 并将此查询追溯到 SQL。 除了索引提示之外的查询是由 Dynamics 生成的,我想知道我是否必须在 AX 中重写整个语句,或者我是否可以通过简单地向索引添加更改来解决这个问题。 查询如下:
SELECT T1.PARTITION, T1.DECIMALPRECISION, T1.RECID, T1.RECVERSION, T1.SYMBOL, T1.SYSTEMOFUNITS, T1.UNITOFMEASURECLASS
FROM UNITOFMEASURE AS T1 WITH(INDEX(I_4436SYMBOLIDX))
WHERE T1.PARTITION = 5637144576 AND EXISTS
(SELECT 'x' AS Expr1
FROM UNITOFMEASURECONVERSION AS T2 WITH(INDEX(I_4438CONVERSIONIDX))
WHERE (T2.PARTITION = 5637144576 )
AND (T2.PRODUCT = 5637297578 OR T2.PRODUCT = 0)
AND (T1.RECID = T2.FROMUNITOFMEASURE)
AND (T2.TOUNITOFMEASURE = 0) OR
(T2.PARTITION = 5637144576) AND (T2.PRODUCT = 5637297578 OR
T2.PRODUCT = 0) AND (T1.RECID = T2.TOUNITOFMEASURE) AND (T2.FROMUNITOFMEASURE = 0))
此查询returns以下执行计划:
可以看到它读取了 5 342544 条记录。相应的表包含 1342 和 3984 条记录。
如果我删除第一个 T1.PARTITION = 5637144576
where 子句,查询将按应有的方式执行。
这是更新后的查询:
SELECT T1.PARTITION, T1.DECIMALPRECISION, T1.RECID, T1.RECVERSION, T1.SYMBOL, T1.SYSTEMOFUNITS, T1.UNITOFMEASURECLASS
FROM UNITOFMEASURE AS T1 WITH(INDEX(I_4436SYMBOLIDX))
WHERE EXISTS
(SELECT 'x' AS Expr1
FROM UNITOFMEASURECONVERSION AS T2 WITH(INDEX(I_4438CONVERSIONIDX))
WHERE (T2.PARTITION = 5637144576 )
AND (T2.PRODUCT = 5637297578 OR T2.PRODUCT = 0)
AND (T1.RECID = T2.FROMUNITOFMEASURE)
AND (T2.TOUNITOFMEASURE = 0) OR
(T2.PARTITION = 5637144576) AND (T2.PRODUCT = 5637297578 OR
T2.PRODUCT = 0) AND (T1.RECID = T2.TOUNITOFMEASURE) AND (T2.FROMUNITOFMEASURE = 0))
现在它使用以下执行计划:
以下是有关所用索引的更多信息:
我可以通过更改索引来优化性能吗? 或者我是否必须通过在 Dynamics AX 2012 中自己构建查询来重写功能。
提前致谢。
您的查询一团糟。 EXISTS
中的 OR
会降低性能。因此,使用多个 EXISTS
子句。我认为是这样的逻辑:
SELECT . . .
FROM UNITOFMEASURE AS T1
WHERE T1.PARTITION = 5637144576 AND
(EXISTS (SELECT 1
FROM UNITOFMEASURECONVERSION T2
WHERE T2.FROMUNITOFMEASURE = T1.RECID AND
T2.PARTITION = 5637144576 AND
T2.PRODUCT IN (5637297578, 0) AND
T2.TOUNITOFMEASURE = 0
) OR
EXISTS (SELECT 1
FROM UNITOFMEASURECONVERSION T2
WHERE T2.TOUNITOFMEASURE = T1.RECID AND
T2.PARTITION = 5637144576 AND
T2.PRODUCT IN (5637297578, 0) AND
T2.FROMUNITOFMEASURE = 0
)
);
那么您需要索引:
UNITOFMEASURE(PARTITION, RECID)
UNITOFMEASURECONVERSION(RECID, PARTITION, PRODUCT, FROMUNITOFMEASURE, TOUNITOFMEASURE)
我认为第二个索引对两个子查询都有用。
实际上,如果我正确解释查询,它可以写成:
SELECT . . .
FROM UNITOFMEASURE AS T1
WHERE T1.PARTITION = 5637144576 AND
EXISTS (SELECT 1
FROM UNITOFMEASURECONVERSION T2
WHERE T2.FROMUNITOFMEASURE = T1.RECID AND
T2.PARTITION = 5637144576 AND
T2.PRODUCT IN (5637297578, 0) AND
(T2.TOUNITOFMEASURE = 0 OR T2.FROMUNITOFMEASURE = 0)
);
并且上述索引应该有效。