4

1 つの日付の実行に約 11 秒かかるクエリがあります。同じクエリを複数日実行したい。つまり、複数日のスナップショットを返せるようにしたいのです。ここに私の元のクエリがあります:

SELECT 
    COUNT(*) AS 'Number of Cars',
    d.ManufacturerName AS 'Make',
    d.Name AS 'Model', 
    c.name AS 'Car Class'
FROM CarRating a 
    INNER JOIN OwnedCar b ON a.OwnedCarID = b.OwnedCarID
    INNER JOIN CarClass c ON a.CarClassID = c.CarClassID
    INNER JOIN BaseCar d ON b.BaseCarID = d.BaseCarID

WHERE 
    @myDate < a.ExpiredWhen AND @myDate  >= a.EffectiveWhen 
GROUP BY 
    d.Name, c.name,d.ManufacturerName

前述したように、クエリについては 11 秒かかります。複数の日付に対してこのクエリを実行するために、日付テーブルを使用し、それを上記のクエリに相互適用しています。

SELECT [DATE], b.* FROM DimDate 
CROSS APPLY
    (SELECT 
        COUNT(*) AS 'Number of Cars',
        d.ManufacturerName AS 'Make',
        d.Name AS 'Model', 
        c.name AS 'Car Class'
    FROM CarRating a 
        INNER JOIN OwnedCar b ON a.OwnedCarID = b.OwnedCarID
        INNER JOIN CarClass c ON a.CarClassID = c.CarClassID
        INNER JOIN BaseCar d ON b.BaseCarID = d.BaseCarID

    WHERE 
    dimDate.Date < a.ExpiredWhen AND dimDate.Date >= a.EffectiveWhen    
    GROUP BY 
    d.Name, c.name,d.ManufacturerName) b

 WHERE DimDate.Date between @StartDate and @EndDate

このクエリは、1 日でも 49 秒かかります。なぜこれが遅いのですか?これを行うより良い方法はありますか?

4

5 に答える 5

2

ディメンション テーブルに結合しているため、クエリが遅くなり、処理されるデータ量が大幅に増加します。適切なインデックスがあることを確認することで、おそらくこのクエリを修正できます。

  • OwnedCar(OwnedCarId)
  • 車クラス(車クラスID)
  • BaseCare(ベースケアID)
  • CarRating(発効時、失効時)

これで解決しない場合は、クエリを再考する必要があります。別の書き方もありますが、索引を使用すると問題をより簡単に解決できる場合があります。

于 2012-10-23T18:34:40.243 に答える
1

本当にクロス適用/サブクエリである必要がありますか? その方法でより多くの作業を行っているようです。結合したままにできませんでしたか?

SELECT 
    dimDate.[Date]
    COUNT(1) AS 'Number of Cars',
    d.ManufacturerName AS 'Make',
    d.Name AS 'Model', 
    c.name AS 'Car Class'
FROM DimDate
LEFT OUTER JOIN CarRating a ON dimDate.[Date] < a.ExpiredWhen AND dimDate.[Date] >= a.EffectiveWhen 
LEFT OUTER JOIN OwnedCar b ON a.OwnedCarID = b.OwnedCarID
LEFT OUTER JOIN CarClass c ON a.CarClassID = c.CarClassID
LEFT OUTER JOIN BaseCar d ON b.BaseCarID = d.BaseCarID
GROUP BY dimDate.[Date], d.Name, c.name,d.ManufacturerName
于 2012-10-23T21:53:07.277 に答える
0

私は自分自身に慣れていませんが、次のように範囲をCROSS APPLY追加してグループ化することはできませんか?ExpiredWhen

SELECT
     a.ExpiredWhen AS dimDate
   , COUNT(*) AS 'Number of Cars'
   , d.ManufacturerName AS 'Make'
   , d.Name AS 'Model'
   , c.name AS 'Car Class' 
FROM CarRating a
INNER JOIN OwnedCar b ON a.OwnedCarID = b.OwnedCarID
INNER JOIN CarClass c ON a.CarClassID = c.CarClassID
INNER JOIN BaseCar d ON b.BaseCarID = d.BaseCarID  
WHERE a.ExpiredWhen between @StartDate AND @EndDate
GROUP BY
   a.ExpiredWhen, d.Name, c.name, d.ManufacturerName
于 2012-10-23T18:35:02.510 に答える
0

以下のようにクエリを変更して、結果を共有していただけますか (改善が見られた場合)

SELECT [DATE], b.* FROM DimDate 
CROSS APPLY
    (SELECT 
        **COUNT(1)** AS 'Number of Cars',
        d.ManufacturerName AS 'Make',
        d.Name AS 'Model', 
        c.name AS 'Car Class'
    FROM CarRating a 
        INNER JOIN OwnedCar b ON a.OwnedCarID = b.OwnedCarID
        **AND  dimDate.Date < a.ExpiredWhen AND dimDate.Date >= a.EffectiveWhen**   
        INNER JOIN CarClass c ON a.CarClassID = c.CarClassID
        INNER JOIN BaseCar d ON b.BaseCarID = d.BaseCarID

    GROUP BY 
    d.Name, c.name,d.ManufacturerName) b

 WHERE DimDate.Date between @StartDate and @EndDate
于 2012-10-23T19:13:14.477 に答える