使用多个连接使SQL查询执行得更好

时间:2014-06-12 18:34:00

标签: sql-server stored-procedures

我有一个存储过程,目前需要4分钟才能运行。我试着把它降到大约2分钟。该查询基本上查看了一个大约25,000行的表。它抓取每个项目,并尝试查找与大约230行的表匹配。

 SET NOCOUNT ON;

DECLARE @Iterator INT
DECLARE @RowCount INT
DECLARE @tempView TABLE (viewID int identity, 
                      intCarrierCode int,
                      chrDlrNum varchar(50),
                      chrPgmCode varchar(5),
                      chrCvgCode varchar(5),
                      chrTransType varchar(5),
                      chrFeeType varchar(5),
                      chrPayeeType varchar(5),
                      intPayeeCode int,
                      Count int,
                      Amount smallmoney);
DECLARE @tempTable TABLE (tableID int identity,
                      inbAcctgID int,
                      chrCarrierDesc varchar(50),
                      chrCarrierDescSht varchar(50),
                      intAcctCustID int,
                      intAcctCo int,
                      intAcctCoRec int,
                      chrPgmCode varchar(5), 
                      intCarrierCode int,
                      chrDlrNum varchar(50),
                      chrCvgCode varchar(5),
                      chrPayeeType varchar(5),
                      chrFeeType varchar(5),
                      intPayeeCode int,
                      chrTransType varchar(5),
                      Count int,
                      Amount smallmoney)

Truncate Table tblPayeeTransactionsMatchMonthEnd

INSERT into @tempView     (intCarrierCode,chrDlrNum,chrPgmCode,chrCvgCode,chrTransType,chrFeeType,chrPayeeType,intPay eeCode,Count,Amount)
SELECT * FROM dbo.viewMonthendArchiveGroupByCovg Where chrPgmCode <> 'BIW' and   chrPayeeType <> 'M' and chrTransType Not in ('CXS','VOD','SUS','DEN') and Amount <> 0


SET @Iterator = 1
SET @RowCount = (SELECT COUNT(*) FROM @tempView)

WHILE (@Iterator <= @RowCount)
BEGIN

IF (Select COUNT(intActgAcctID) 
From dbo.tblActgPayeeTransactionAccounts2 as A INNER JOIN @tempView as V
    ON A.chrPgmCode = V.chrPgmCode
        and A.intCarrierCode = V.intCarrierCode
        and A.chrPayeeType = V.chrPayeeType
        and A.chrFeeType = V.chrFeeType
        and (A.intPayeeCode = V.intPayeeCode OR A.intPayeeCode is NULL)
        and (A.chrCvgCode = V.chrCvgCode OR A.chrCvgCode is NULL)
        and (A.chrDlrNum = V.chrDlrNum OR A.chrDlrNum is NULL)
        and (A.chrTransType = V.chrTransType OR A.chrTransType IS NULL)
    where V.viewID = @Iterator) = 1
BEGIN
    INSERT INTO @tempTable (inbAcctgID,chrCarrierDesc,chrCarrierDescSht,intAcctCustID,intAcctCo,intAcctCoRec,chrPgmCode,intCarrierCode,chrDlrNum,chrCvgCode,chrPayeeType,chrFeeType,intPayeeCode,chrTransType,Count,Amount)
       (Select A.inbAcctgID,A.chrCarrierDesc,A.chrCarrierDescSht,A.intAcctCustID,A.intAcctCo,A.intAcctCoRec,A.chrPgmCode,A.intCarrierCode,V.chrDlrNum,V.chrCvgCode,V.chrPayeeType,V.chrFeeType,V.intPayeeCode,V.chrTransType,V.Count,V.Amount
        From dbo.tblActgPayeeTransactionAccounts as A INNER JOIN @tempView as V
        ON A.chrPgmCode = V.chrPgmCode
            and A.intCarrierCode = V.intCarrierCode
            and A.chrPayeeType = V.chrPayeeType
            and A.chrFeeType = V.chrFeeType
            and (A.intPayeeCode = V.intPayeeCode OR A.intPayeeCode is NULL)
            and (A.chrCvgCode = V.chrCvgCode OR A.chrCvgCode is NULL)
            and (A.chrDlrNum = V.chrDlrNum OR A.chrDlrNum is NULL)
            and (A.chrTransType = V.chrTransType OR A.chrTransType IS NULL)
        where V.viewID = @Iterator)
END
ELSE IF (Select COUNT(intActgAcctID) 
From dbo.tblActgPayeeTransactionAccounts2 as A INNER JOIN @tempView as V
    ON A.chrPgmCode = V.chrPgmCode
        and A.intCarrierCode = V.intCarrierCode
        and A.chrPayeeType = V.chrPayeeType
        and A.chrFeeType = V.chrFeeType
        and (A.intPayeeCode = V.intPayeeCode OR A.intPayeeCode is NULL)
        and (A.chrCvgCode = V.chrCvgCode OR A.chrCvgCode is NULL)
        and (A.chrDlrNum = V.chrDlrNum OR A.chrDlrNum is NULL)
    where V.viewID = @Iterator) = 1
BEGIN
    INSERT INTO @tempTable (inbAcctgID,chrCarrierDesc,chrCarrierDescSht,intAcctCustID,intAcctCo,intAcctCoRec,chrPgmCode,intCarrierCode,chrDlrNum,chrCvgCode,chrPayeeType,chrFeeType,intPayeeCode,chrTransType,Count,Amount)
       (Select A.inbAcctgID,A.chrCarrierDesc,A.chrCarrierDescSht,A.intAcctCustID,A.intAcctCo,A.intAcctCoRec,A.chrPgmCode,A.intCarrierCode,V.chrDlrNum,V.chrCvgCode,V.chrPayeeType,V.chrFeeType,V.intPayeeCode,V.chrTransType,V.Count,V.Amount
        From dbo.tblActgPayeeTransactionAccounts as A INNER JOIN @tempView as V
        ON A.chrPgmCode = V.chrPgmCode
            and A.intCarrierCode = V.intCarrierCode
            and A.chrPayeeType = V.chrPayeeType
            and A.chrFeeType = V.chrFeeType
            and (A.intPayeeCode = V.intPayeeCode OR A.intPayeeCode is NULL)
            and (A.chrCvgCode = V.chrCvgCode OR A.chrCvgCode is NULL)
            and (A.chrDlrNum = V.chrDlrNum OR A.chrDlrNum is NULL)
        where V.viewID = @Iterator)
END
ELSE IF (Select COUNT(intActgAcctID) 
From dbo.tblActgPayeeTransactionAccounts2 as A INNER JOIN @tempView as V
    ON A.chrPgmCode = V.chrPgmCode
        and A.intCarrierCode = V.intCarrierCode
        and A.chrPayeeType = V.chrPayeeType
        and A.chrFeeType = V.chrFeeType
        and (A.intPayeeCode = V.intPayeeCode OR A.intPayeeCode is NULL)
        and (A.chrCvgCode = V.chrCvgCode OR A.chrCvgCode is NULL)
    where V.viewID = @Iterator) = 1
BEGIN
    INSERT INTO @tempTable (inbAcctgID,chrCarrierDesc,chrCarrierDescSht,intAcctCustID,intAcctCo,intAcctCoRec,chrPgmCode,intCarrierCode,chrDlrNum,chrCvgCode,chrPayeeType,chrFeeType,intPayeeCode,chrTransType,Count,Amount)
       (Select A.inbAcctgID,A.chrCarrierDesc,A.chrCarrierDescSht,A.intAcctCustID,A.intAcctCo,A.intAcctCoRec,A.chrPgmCode,A.intCarrierCode,V.chrDlrNum,V.chrCvgCode,V.chrPayeeType,V.chrFeeType,V.intPayeeCode,V.chrTransType,V.Count,V.Amount
        From dbo.tblActgPayeeTransactionAccounts as A INNER JOIN @tempView as V
        ON A.chrPgmCode = V.chrPgmCode
            and A.intCarrierCode = V.intCarrierCode
            and A.chrPayeeType = V.chrPayeeType
            and A.chrFeeType = V.chrFeeType
            and (A.intPayeeCode = V.intPayeeCode OR A.intPayeeCode is NULL)
            and (A.chrCvgCode = V.chrCvgCode OR A.chrCvgCode is NULL)
        where V.viewID = @Iterator)
END
ELSE IF (Select COUNT(intActgAcctID) 
From dbo.tblActgPayeeTransactionAccounts2 as A INNER JOIN @tempView as V
    ON A.chrPgmCode = V.chrPgmCode
        and A.intCarrierCode = V.intCarrierCode
        and A.chrPayeeType = V.chrPayeeType
        and A.chrFeeType = V.chrFeeType
        and A.intPayeeCode = V.intPayeeCode
    where V.viewID = @Iterator) = 1
BEGIN
    INSERT INTO @tempTable (inbAcctgID,chrCarrierDesc,chrCarrierDescSht,intAcctCustID,intAcctCo,intAcctCoRec,chrPgmCode,intCarrierCode,chrDlrNum,chrCvgCode,chrPayeeType,chrFeeType,intPayeeCode,chrTransType,Count,Amount)
       (Select A.inbAcctgID,A.chrCarrierDesc,A.chrCarrierDescSht,A.intAcctCustID,A.intAcctCo,A.intAcctCoRec,A.chrPgmCode,A.intCarrierCode,V.chrDlrNum,V.chrCvgCode,V.chrPayeeType,V.chrFeeType,V.intPayeeCode,V.chrTransType,V.Count,V.Amount
        From dbo.tblActgPayeeTransactionAccounts as A INNER JOIN @tempView as V
        ON A.chrPgmCode = V.chrPgmCode
            and A.intCarrierCode = V.intCarrierCode
            and A.chrPayeeType = V.chrPayeeType
            and A.chrFeeType = V.chrFeeType
            and (A.intPayeeCode = V.intPayeeCode)
        where V.viewID = @Iterator)
END
ELSE IF (Select COUNT(intActgAcctID) 
From dbo.tblActgPayeeTransactionAccounts2 as A INNER JOIN @tempView as V
    ON A.chrPgmCode = V.chrPgmCode
        and A.intCarrierCode = V.intCarrierCode
        and A.chrPayeeType = V.chrPayeeType
        and A.chrFeeType = V.chrFeeType
        and A.intPayeeCode is NULL
    where V.viewID = @Iterator) = 1
BEGIN
    INSERT INTO @tempTable (inbAcctgID,chrCarrierDesc,chrCarrierDescSht,intAcctCustID,intAcctCo,intAcctCoRec,chrPgmCode,intCarrierCode,chrDlrNum,chrCvgCode,chrPayeeType,chrFeeType,intPayeeCode,chrTransType,Count,Amount)
       (Select A.inbAcctgID,A.chrCarrierDesc,A.chrCarrierDescSht,A.intAcctCustID,A.intAcctCo,A.intAcctCoRec,A.chrPgmCode,A.intCarrierCode,V.chrDlrNum,V.chrCvgCode,V.chrPayeeType,V.chrFeeType,V.intPayeeCode,V.chrTransType,V.Count,V.Amount
        From dbo.tblActgPayeeTransactionAccounts as A INNER JOIN @tempView as V
        ON A.chrPgmCode = V.chrPgmCode
            and A.intCarrierCode = V.intCarrierCode
            and A.chrPayeeType = V.chrPayeeType
            and A.chrFeeType = V.chrFeeType
            and A.intPayeeCode is NULL
        where V.viewID = @Iterator)
END
ELSE IF (Select COUNT(intActgAcctID) 
From dbo.tblActgPayeeTransactionAccounts2 as A INNER JOIN @tempView as V
    ON A.chrPgmCode = V.chrPgmCode
        and A.intCarrierCode = V.intCarrierCode
        and A.chrPayeeType = V.chrPayeeType
        and A.chrFeeType = V.chrFeeType
    where V.viewID = @Iterator) = 1
BEGIN
    INSERT INTO @tempTable (inbAcctgID,chrCarrierDesc,chrCarrierDescSht,intAcctCustID,intAcctCo,intAcctCoRec,chrPgmCode,intCarrierCode,chrDlrNum,chrCvgCode,chrPayeeType,chrFeeType,intPayeeCode,chrTransType,Count,Amount)
       (Select A.inbAcctgID,A.chrCarrierDesc,A.chrCarrierDescSht,A.intAcctCustID,A.intAcctCo,A.intAcctCoRec,A.chrPgmCode,A.intCarrierCode,V.chrDlrNum,V.chrCvgCode,V.chrPayeeType,V.chrFeeType,V.intPayeeCode,V.chrTransType,V.Count,V.Amount
        From dbo.tblActgPayeeTransactionAccounts as A INNER JOIN @tempView as V
        ON A.chrPgmCode = V.chrPgmCode
            and A.intCarrierCode = V.intCarrierCode
            and A.chrPayeeType = V.chrPayeeType
            and A.chrFeeType = V.chrFeeType
        where V.viewID = @Iterator)
END
ELSE IF (Select COUNT(intActgAcctID) 
From dbo.tblActgPayeeTransactionAccounts2 as A INNER JOIN @tempView as V
    ON A.chrPgmCode = V.chrPgmCode
        and A.intCarrierCode = V.intCarrierCode
        and A.chrPayeeType = V.chrPayeeType
    where V.viewID = @Iterator) = 1
BEGIN
    INSERT INTO @tempTable (inbAcctgID,chrCarrierDesc,chrCarrierDescSht,intAcctCustID,intAcctCo,intAcctCoRec,chrPgmCode,intCarrierCode,chrDlrNum,chrCvgCode,chrPayeeType,chrFeeType,intPayeeCode,chrTransType,Count,Amount)
       (Select A.inbAcctgID,A.chrCarrierDesc,A.chrCarrierDescSht,A.intAcctCustID,A.intAcctCo,A.intAcctCoRec,A.chrPgmCode,A.intCarrierCode,V.chrDlrNum,V.chrCvgCode,V.chrPayeeType,V.chrFeeType,V.intPayeeCode,V.chrTransType,V.Count,V.Amount
        From dbo.tblActgPayeeTransactionAccounts as A INNER JOIN @tempView as V
        ON A.chrPgmCode = V.chrPgmCode
            and A.intCarrierCode = V.intCarrierCode
            and A.chrPayeeType = V.chrPayeeType
        where V.viewID = @Iterator)
END
ELSE IF (Select COUNT(intActgAcctID) 
From dbo.tblActgPayeeTransactionAccounts2 as A INNER JOIN @tempView as V
    ON A.chrPgmCode = V.chrPgmCode
        and A.intCarrierCode = V.intCarrierCode
    where V.viewID = @Iterator) = 1
BEGIN
    INSERT INTO @tempTable (inbAcctgID,chrCarrierDesc,chrCarrierDescSht,intAcctCustID,intAcctCo,intAcctCoRec,chrPgmCode,intCarrierCode,chrDlrNum,chrCvgCode,chrPayeeType,chrFeeType,intPayeeCode,chrTransType,Count,Amount)
       (Select A.inbAcctgID,A.chrCarrierDesc,A.chrCarrierDescSht,A.intAcctCustID,A.intAcctCo,A.intAcctCoRec,A.chrPgmCode,A.intCarrierCode,V.chrDlrNum,V.chrCvgCode,V.chrPayeeType,V.chrFeeType,V.intPayeeCode,V.chrTransType,V.Count,V.Amount
        From dbo.tblActgPayeeTransactionAccounts as A INNER JOIN @tempView as V
        ON A.chrPgmCode = V.chrPgmCode
            and A.intCarrierCode = V.intCarrierCode
        where V.viewID = @Iterator)
END
ELSE IF (Select COUNT(intActgAcctID) 
From dbo.tblActgPayeeTransactionAccounts2 as A INNER JOIN @tempView as V
    ON A.chrPgmCode = V.chrPgmCode
    where V.viewID = @Iterator) = 1
BEGIN
    INSERT INTO @tempTable (inbAcctgID,chrCarrierDesc,chrCarrierDescSht,intAcctCustID,intAcctCo,intAcctCoRec,chrPgmCode,intCarrierCode,chrDlrNum,chrCvgCode,chrPayeeType,chrFeeType,intPayeeCode,chrTransType,Count,Amount)
       (Select A.inbAcctgID,A.chrCarrierDesc,A.chrCarrierDescSht,A.intAcctCustID,A.intAcctCo,A.intAcctCoRec,A.chrPgmCode,A.intCarrierCode,V.chrDlrNum,V.chrCvgCode,V.chrPayeeType,V.chrFeeType,V.intPayeeCode,V.chrTransType,V.Count,V.Amount
        From dbo.tblActgPayeeTransactionAccounts as A INNER JOIN @tempView as V
        ON A.chrPgmCode = V.chrPgmCode
        where V.viewID = @Iterator)
END
ELSE
BEGIN
    INSERT INTO @tempTable (inbAcctgID,chrCarrierDesc,chrCarrierDescSht,intAcctCustID,intAcctCo,intAcctCoRec,chrPgmCode,intCarrierCode,chrDlrNum,chrCvgCode,chrPayeeType,chrFeeType,intPayeeCode,chrTransType,Count,Amount)
        (SELECT NULL,NULL,NULL,NULL,NULL,NULL,V.chrPgmCode,V.intCarrierCode, V.chrDlrNum,V.chrCvgCode,V.chrPayeeType,V.chrFeeType,V.intPayeeCode,V.chrTransType,V.Count,V.Amount
        FROM @tempView as V
        where V.viewID = @Iterator)
END

Set @Iterator = @Iterator + 1
END 

Begin

Insert into    tblPayeeTransactionsMatchMonthEnd(inbAcctgID,chrCarrierDesc,chrCarrierDescSht,intAcctCustID,intAcctCo,intAcctCoRec,chrPgmCode,intCarrierCode,chrDlrNum,chrCvgCode,chrPayeeType,chrFeeType,intPayeeCode,chrTransType,Count,Amount)
Select inbAcctgID,chrCarrierDesc,chrCarrierDescSht,intAcctCustID,intAcctCo,intAcctCoRec,chrPgmCode,intCarrierCode,chrDlrNum,chrCvgCode,chrPayeeType,chrFeeType,intPayeeCode,chrTransType,Count,Amount from @tempTable

End`

抱歉长度。任何帮助将非常感激。我试过从Select Count(*)到Count只计算一列,但它没有区别。

2 个答案:

答案 0 :(得分:1)

很难说出什么是错误的,但首先应检查表中字段中的索引,这些索引用于where子句和ON内联接中。 我也看到了这样的语法:

if(select count(1) from t where something= something) = 1
begin
   insert into A from t where something= something
end

这是不好的做法。使用就像这样:

begin tran
       insert into A from t where something= something
if @@rowcount > 1 -- this is you requirement that needs just one row needs instead of if(select count(1) from t where something= something) = 1
  rollback tran
else
  commit tran

在这种情况下,您只有一个select而不是两个set statistics time on go set statistics io on go 。有很多这样的情况,如果仔细改变,你会得到更好的表现

此外,您还可以包含客户端统计信息(I / O和时间)

{{1}}

您将看到查询工作的一部分正是缓慢的。

答案 1 :(得分:0)

所有IF结构等同于

IF (Select COUNT(intActgAcctID) 
From dbo.tblActgPayeeTransactionAccounts2 as A INNER JOIN @tempView as V
    ON A.chrPgmCode = V.chrPgmCode
    where V.viewID = @Iterator) = 1
BEGIN
    INSERT INTO @tempTable (inbAcctgID,chrCarrierDesc,chrCarrierDescSht,intAcctCustID,intAcctCo,intAcctCoRec,chrPgmCode,intCarrierCode,chrDlrNum,chrCvgCode,chrPayeeType,chrFeeType,intPayeeCode,chrTransType,Count,Amount)
       (Select A.inbAcctgID,A.chrCarrierDesc,A.chrCarrierDescSht,A.intAcctCustID,A.intAcctCo,A.intAcctCoRec,A.chrPgmCode,A.intCarrierCode,V.chrDlrNum,V.chrCvgCode,V.chrPayeeType,V.chrFeeType,V.intPayeeCode,V.chrTransType,V.Count,V.Amount
        From dbo.tblActgPayeeTransactionAccounts as A INNER JOIN @tempView as V
        ON A.chrPgmCode = V.chrPgmCode
        where V.viewID = @Iterator)
END
ELSE
BEGIN
    INSERT INTO @tempTable (inbAcctgID,chrCarrierDesc,chrCarrierDescSht,intAcctCustID,intAcctCo,intAcctCoRec,chrPgmCode,intCarrierCode,chrDlrNum,chrCvgCode,chrPayeeType,chrFeeType,intPayeeCode,chrTransType,Count,Amount)
        (SELECT NULL,NULL,NULL,NULL,NULL,NULL,V.chrPgmCode,V.intCarrierCode, V.chrDlrNum,V.chrCvgCode,V.chrPayeeType,V.chrFeeType,V.intPayeeCode,V.chrTransType,V.Count,V.Amount
        FROM @tempView as V
        where V.viewID = @Iterator)
END
如果chrPgmCode上的检查要将数据传递给@tempTable

,则无需检查每列的列数

这意味着如果tblActgPayeeTransactionAccounts2tblActgPayeeTransactionAccounts 拥有相同的数据

INSERT INTO @tempTable (inbAcctgID,chrCarrierDesc,chrCarrierDescSht,intAcctCustID,intAcctCo,intAcctCoRec,chrPgmCode,intCarrierCode,chrDlrNum,chrCvgCode,chrPayeeType,chrFeeType,intPayeeCode,chrTransType,Count,Amount)
SELECT A.inbAcctgID,A.chrCarrierDesc,A.chrCarrierDescSht,A.intAcctCustID,A.intAcctCo,A.intAcctCoRec,A.chrPgmCode,A.intCarrierCode,V.chrDlrNum,V.chrCvgCode,V.chrPayeeType,V.chrFeeType,V.intPayeeCode,V.chrTransType,V.Count,V.Amount
FROM dbo.tblActgPayeeTransactionAccounts as A 
     INNER JOIN @tempView as V ON A.chrPgmCode = V.chrPgmCode

INSERT INTO @tempTable (inbAcctgID,chrCarrierDesc,chrCarrierDescSht,intAcctCustID,intAcctCo,intAcctCoRec,chrPgmCode,intCarrierCode,chrDlrNum,chrCvgCode,chrPayeeType,chrFeeType,intPayeeCode,chrTransType,Count,Amount)
SELECT NULL,NULL,NULL,NULL,NULL,NULL,V.chrPgmCode,V.intCarrierCode, V.chrDlrNum,V.chrCvgCode,V.chrPayeeType,V.chrFeeType,V.intPayeeCode,V.chrTransType,V.Count,V.Amount
FROM   @tempView as V
where  NOT EXISTS (SELECT 1
                   FROM   dbo.tblActgPayeeTransactionAccounts as A 
                          INNER JOIN @tempView as V ON A.chrPgmCode = V.chrPgmCode
                  )

没有任何游标或迭代器