在Axapta数据库上查询的性能问题

时间:2014-07-09 10:02:27

标签: sql sql-server sql-server-2005 axapta

我在Axapta数据库上写了一个查询并重写了一百次,但问题仍然存在。它表现非常糟糕。 15分钟后,几乎没有结果,几乎让服务器停机。

欢迎任何有关如何改进此声明的想法。

SELECT
  J.INVOICEID,
  T.AMOUNTCUR,
  T.RECID,
  T.ACCOUNTNUM,
  CASE WHEN O.DATAAREAID IS NULL THEN 0 ELSE 1 END hasOpenTrans,
  CASE WHEN P.DATAAREAID IS NULL THEN 0 ELSE 1 END hasPayment
FROM
  CUSTINVOICEJOUR J
  LEFT JOIN CUSTTRANS T ON
    T.DATAAREAID = J.DATAAREAID AND
    T.INVOICE = J.INVOICEID AND
    T.ACCOUNTNUM = J.INVOICEACCOUNT AND
    T.TRANSDATE = J.INVOICEDATE
  LEFT JOIN (
    SELECT
      DATAAREAID,
      REFRECID,
      ACCOUNTNUM
    FROM
      CUSTTRANSOPEN
    GROUP BY
      DATAAREAID,
      REFRECID,
      ACCOUNTNUM
    HAVING
      COUNT(*) > 0) O ON
        O.DATAAREAID = T.DATAAREAID AND
        O.REFRECID = T.RECID AND
        O.ACCOUNTNUM = T.ACCOUNTNUM
  LEFT JOIN (
    SELECT
      S.DATAAREAID,
      S.TRANSCOMPANY,
      S.TRANSRECID,
      S.ACCOUNTNUM
    FROM CUSTSETTLEMENT S 
      INNER JOIN CUSTTRANS C ON 
        C.DATAAREAID = S.DATAAREAID AND 
        C.RECID = S.OFFSETRECID AND 
        C.TRANSTYPE IN (0, 8, 15) AND 
        S.CANBEREVERSED = 1
    GROUP BY
      S.DATAAREAID,
      S.TRANSRECID,
      S.TRANSCOMPANY,
      S.ACCOUNTNUM
    HAVING
      SUM(S.SETTLEAMOUNTCUR) > 0) P ON
        P.DATAAREAID = T.DATAAREAID AND
        P.TRANSRECID = T.RECID AND
        P.ACCOUNTNUM = T.ACCOUNTNUM AND
        P.TRANSCOMPANY = T.DATAAREAID
WHERE
  J.DATAAREAID = '011' AND
  J.INVOICEDATE >= '2014-06-01'

因为它可能很重要:这里是涉及的表上的现有索引:

CUSTINVOICEJOUR
Index Name               Columns                                                        Clustered   Primary Key   Unique
I_062INVOICEACCOUNTIDX   DATAAREAID, INVOICEACCOUNT, INVOICEDATE                        False       False         False
I_062INVOICENUMIDX       DATAAREAID, INVOICEID, INVOICEDATE, NUMBERSEQUENCEGROUP, RECID True        False         True
I_062ORDERACCOUNTIDX     DATAAREAID, ORDERACCOUNT, INVOICEDATE                          False       False         False
I_062PARMIDX             DATAAREAID, PARMID                                             False       False         False
I_062RECID               DATAAREAID, RECID                                              False       True          True
I_062SALESIDDATEIDX      DATAAREAID, SALESID, REFNUM, INVOICEDATE                       False       False         False
I_062VATNUMIDX           DATAAREAID, VATNUM                                             False       False         False

CUSTTRANS
Index Name               Columns                                    Clustered   Primary Key   Unique
I_078ACCOUNTDATEIDX      DATAAREAID, ACCOUNTNUM, TRANSDATE          True        False         False
I_078BILLOFEXCHANGEIDX   DATAAREAID, BILLOFEXCHANGEID               False       False         False
I_078INVACCOUNTDATEIDX   DATAAREAID, INVOICE, ACCOUNTNUM, TRANSDATE False       False         False
I_078INVOICEACCOUNTIDX   DATAAREAID, INVOICE, ACCOUNTNUM            False       False         False
I_078PAYMIDDATEIDX       DATAAREAID, PAYMID, TRANSDATE              False       False         False
I_078RECID               DATAAREAID, RECID                          False       True          True
I_078VOUCHERDATEIDX      DATAAREAID, VOUCHER, TRANSDATE             False       False         False

CUSTTRANSOPEN
Index Name            Columns                           Clustered   Primary Key   Unique
I_865ACCOUNTDATEIDX   DATAAREAID, ACCOUNTNUM, TRANSDATE True        False         False
I_865RECID            DATAAREAID, RECID                 False       True          True
I_865REFRECIDX        DATAAREAID, REFRECID              False       False         False

CUSTSETTLEMENT
Index Name                       Columns                                                               Clustered   Primary Key   Unique
I_075OFFSETCOMPANYRECTRANSREC7   DATAAREAID, OFFSETCOMPANY, OFFSETRECID, TRANSRECID, SETTLEMENTGROUP   False       False         False
I_075OFFSETVOUCHERIDX            DATAAREAID, OFFSETTRANSVOUCHER                                        False       False         False
I_075RECID                       DATAAREAID, RECID                                                     False       True          True
I_075SETTLEMENTGROUPIDX          DATAAREAID, SETTLEMENTGROUP                                           False       False         False
I_075TRANSINDEX                  DATAAREAID, TRANSRECID, TRANSDATE                                     True        False         False

表格的大小也可能很重要,或者至少可以了解我正在处理的记录数量:

CUSTINVOICEJOUR
DATAAREAID       Nbr
011          1513668
012                2
ash           355735
bar           268795
euk           692242
hlm           866154
lil           136163
prv             3180

CUSTTRANS
DATAAREAID       Nbr
011          2383870
012                4
ash           428161
bar           367620
bol               45
euk           630029
hlm          1377005
lil           167405
prv             4148

CUSTTRANSOPEN
DATAAREAID    Nbr
011          6119
012             4
ash          5845
bar          1876
bol            29
euk          8077
hlm          2426
lil          2173
prv           190

CUSTSETTLEMENT
DATAAREAID       Nbr
011          2469546
ash           462982
bar           415329
bol               18
euk           684421
hlm          1419857
lil           178551
prv             4325

2 个答案:

答案 0 :(得分:0)

在不了解执行计划或各列数据的selectivity的情况下,并考虑到您发布的查询和索引,尝试在表上创建覆盖索引可能是值得的。

快速浏览一下查询会引导我查看所涉及的表的以下索引(基本上使用WHERE子句中涉及的每一列,或JOIN

CUSTINVOICEJOUR - DATAAREAID, INVOICEID, NVOICEACCOUNT, INVOICEDATE, RECID, ACCOUNTNUM
CUSTTRANS - DATAAREAID, INVOICE, ACCOUNTNUM, TRANSDATE, RECID
CUSTTRANSOPEN - DATAAREAID, REFRECID, ACCOUNTNUM
CUSTSETTLEMENT - DATAAREAID, RECID, TRANSTYPE, CANBEREVERSED, TRANSRECID, ACCOUNTNUM, TRANSCOMPANY

请记住,列的上述顺序基于我在查询中发现它们的顺序。为了找出理想的顺序,确定每列的选择性,并根据它从高选择性到低的顺序对它们进行排序。

在添加新索引之前尝试并记录选择性路径,然后添加索引并再次检查执行路径以查看是否正在使用新索引(它们应该是。如果不是,它可能表示列缺失)。然后转到下一个索引,同时关注你刚刚添加的索引,看看你刚刚添加的索引是否会影响刚刚执行的路径(如果你抓到所有索引,就不会发生这种情况)使用的列,但这种行为永远不能排除100%)。

要注意的另一件好事是服务器返回的统计信息。添加新索引时,目标应该是降低物理读取量(基于磁盘的搜索),并将它们转换为逻辑读取(从内存中更便宜)。

您的里程可能会有所不同,但上述情况会让您有个良好的开端。

答案 1 :(得分:0)

也许somthing配置错误或某些其他进程正在锁定表格? 我在一个本地数据库上执行了你的查询,它在大约1秒内执行。

查看SQL服务器上的运行进程并搜索锁。 您可以使用查询分析器,它是SSMS的一部分。

来自这个地方的执行计划: enter image description here