0

いくつかのかなり大きなテーブルに対して実行するストアド プロシージャがあり、より大きなテーブルに結合している間、対応する batch_id に一致するレコード数の集計も保持しています。私が理解しようとしているのは、カウントの関数またはその他の手段でこれを改善できるかということです。ネストされた SELECT COUNT(*) ステートメントを取り除こうとしています。CCTransactions テーブルは 140 万行で、BatchItems は 660 万行です。

SELECT  a.ItemAuthID, a.FeeAuthID, a.Batch_ID, a.ItemAuthCode, 
        a.FeeAuthCode, b.Amount, b.Fee, 
  (SELECT COUNT(*) FROM BatchItems WHERE Batch_ID = a.Batch_ID) AS BatchCount,
  ItemBillDate, FeeBillDate, b.AccountNumber, 
  b.Itemcode, ItemAuthToken, FeeAuthToken,
  cc.ItemMerchant, cc.FeeMerchant
  FROM CCTransactions a WITH(NOLOCK)
        INNER JOIN BatchItems b WITH(NOLOCK)
              ON a.Batch_ID = b.Batch_ID
        INNER JOIN CCConfig cc WITH(NOLOCK)
              ON a.ClientCode = cc.ClientCode
  WHERE ((ItemAuthCode > '' AND ItemBillDate IS NULL)
              OR (FeeAuthCode > '' AND FeeBillDate IS NULL))
              AND TransactionDate BETWEEN DATEADD(d,-7,GETDATE()) 
              AND convert(char(20),getdate(),101)  + ' ' +   @Cutoff
  ORDER BY TransactionDate
4

1 に答える 1

0

DBMS が WINdowed Aggregate Functions をサポートしている場合は、それを次のように書き換えることができます。

COUNT(*) OVER (PARTITION BY Batch_ID)

もちろん、これは SELECT によって返される Batch_ID ごとの行数のみを返します。内部結合によって行が少なくなる場合、それは正しい数ではありません。

次に、(DBMS によっては) Scalar Subquery を結合に書き直す方が効率的かもしれません。

SELECT  a.ItemAuthID, a.FeeAuthID, a.Batch_ID, a.ItemAuthCode, 
        a.FeeAuthCode, b.Amount, b.Fee, 
  dt.BatchCount,
  ItemBillDate, FeeBillDate, b.AccountNumber, 
  b.Itemcode, ItemAuthToken, FeeAuthToken,
  cc.ItemMerchant, cc.FeeMerchant
  FROM CCTransactions a WITH(NOLOCK)
        INNER JOIN BatchItems b WITH(NOLOCK)
              ON a.Batch_ID = b.Batch_ID
        INNER JOIN CCConfig cc WITH(NOLOCK)
              ON a.ClientCode = cc.ClientCode
        INNER JOIN
          ( 
            SELECT BatchCount, COUNT(*) AS BatchCount
            FROM BatchItems 
            GROUP BY Batch_ID
          ) AS dt ON a.Batch_ID = dt.Batch_ID
  WHERE ((ItemAuthCode > '' AND ItemBillDate IS NULL)
              OR (FeeAuthCode > '' AND FeeBillDate IS NULL))
              AND TransactionDate BETWEEN DATEADD(d,-7,GETDATE()) 
              AND convert(CHAR(20),getdate(),101)  + ' ' +   @Cutoff
  ORDER BY TransactionDate
于 2013-08-30T15:08:02.343 に答える