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 = 5637144576where 子句,查询将按应有的方式执行。 这是更新后的查询:

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)
             );

并且上述索引应该有效。