2016-08-13 52 views
0

我有一个大型数据库(大小为1.7TB),并有一个维护索引作业来重建索引。这项工作安排在晚上11点。如何在索引作业的同时执行大型查询?

今天早上,我只是检查在服务器上运行的查询,我注意到索引作业仍在运行(超过10小时),因为另一个在服务器上运行的t-sql查询超过22小时,并锁定表格,表明该工作正试图重建它的索引。这就像一个无休止的进展,所以我不得不杀死阻塞会话(169)让索引作业继续运行。我的问题是;我如何避免索引作业正在工作的锁定表。我知道重建索引正在将表bcs锁定为脱机状态,但是我应该对运行超过22小时的t-sql查询进行一些优化吗? Bcs这个t-sql查询当天由我们的ERP应用程序经常运行。

查询是;

SELECT T1.ACCOUNTNUM,T1.AMOUNTCUR,T1.AMOUNTMST,T1.DUEDATE,T1.RECID,T1.RECVERSION,T1.REFRECID,T1.TRANSDATE,T1.RECVERSION,T2.INVOICE 
,T2.TRANSTYPE,T2.TRANSDATE,T2.AMOUNTCUR,T2.ACCOUNTNUM,T2.VOUCHER,T2.COLLECTIONLETTERCODE,T2.SETTLEAMOUNTCUR,T2.CURRENCYCODE, 
T2.CUSTBILLINGCLASSIFICATION,T2.RECVERSION,T2.RECID,T3.ACCOUNTNUM,T3.PARTY,T3.CURRENCY,T3.RECID,T3.RECVERSION 
FROM **CUSTTRANSOPEN** T1 
CROSS JOIN CUSTTRANS T2 
CROSS JOIN CUSTTABLE T3 

WHERE ((([email protected]) AND ([email protected])) AND (T1.DUEDATE<@P3)) AND ((([email protected]) AND 
([email protected])) AND (((((((T2.TRANSTYPE<[email protected]) OR ([email protected])) OR (([email protected]) OR ([email protected]))) 
    OR ((([email protected]) OR ([email protected])) OR ([email protected]))) AND (T2.AMOUNTCUR>[email protected])) 
AND (T1.ACCOUNTNUM=T2.ACCOUNTNUM)) AND (T1.REFRECID=T2.RECID))) AND ((([email protected]) AND ([email protected])) 
    AND (T2.ACCOUNTNUM=T3.ACCOUNTNUM)) ORDER BY T1.DUEDATE OPTION(FAST 5) 

**被锁定的表是:CUSTTRANSOPEN

我的意思是,为前。我应该在查询中放入WITH(NOLOCK)语句吗? 如何使用索引作业同时执行大型查询?

**我有非标准版本的sql server。所以'在线重建'是不可能的。

enter image description here

回答

1

你有两个问题:
- 大的查询,这可能会被调整
- 同时运行ALTER INDEX

  1. 调整查询:
    • 你可能只是把NOLOCK如果你不关心结果。
    • 您的查询字词笛卡尔连接,这应该产生所有三个表中的行的乘法。难怪需要20个小时。这可能不是这个意图。所以,确定你想要什么。以下是简化查询的示例。验证是否能产生同样的逻辑:

SELECT T1.ACCOUNTNUM, T1.AMOUNTCUR, T1.AMOUNTMST, T1.DUEDATE, T1.RECID , T1.RECVERSION, T1.REFRECID, T1.TRANSDATE, T1.RECVERSION, T2.INVOICE , T2.TRANSTYPE, T2.TRANSDATE, T2.AMOUNTCUR, T2.ACCOUNTNUM, T2.VOUCHER , T2.COLLECTIONLETTERCODE, T2.SETTLEAMOUNTCUR, T2.CURRENCYCODE, T2.CUSTBILLINGCLASSIFICATION, T2.RECVERSION , T2.RECID, T3.ACCOUNTNUM, T3.PARTY, T3.CURRENCY, T3.RECID, T3.RECVERSION FROM **CUSTTRANSOPEN** AS T1 INNER JOIN CUSTTRANS AS T2 ON T1.ACCOUNTNUM=T2.ACCOUNTNUM AND T1.REFRECID=T2.RECID AND [email protected] AND [email protected] AND T2.AMOUNTCUR>[email protected] AND (T2.TRANSTYPE<[email protected] OR T2.TRANSTYPE IN (@P7, @P8, @P9, @P10, @P11, @P12) INNER JOIN CUSTTABLE AS T3 ON T2.ACCOUNTNUM=T3.ACCOUNTNUM AND [email protected] AND [email protected] AND WHERE [email protected] AND [email protected] AND T1.DUEDATE<@P3 AND ORDER BY T1.DUEDATE OPTION (FAST 5);

  • 你不得不看的执行计划
  • 看,如果计划是更好,如果你排除OPTION (FAST 5)
  • 见如果您可以通过索引改进查询。

    1. 您可以在排除CUSTTRANSOPEN表的情况下逐个更改索引。并改变其索引时查询已完成。