1

次のコードを SQL クエリに追加しました: (メモ カット ダウン バージョン)

DECLARE @rowType AS TABLE (
    rowTypeLabel NVARCHAR (20));

INSERT  INTO @rowType
VALUES ('Cumulative');

INSERT  INTO @rowType
VALUES ('Non-Cumulative');

--select * from @rowType


SELECT ID,Name,StartDate,
       EndDate,
       rowTypeLabel AS Period
FROM   dbo.sicky CROSS JOIN @rowType
WHERE  (rowTypeLabel = 'Cumulative'
        OR (rowTypeLabel = 'Non-Cumulative'
            AND (EndDate IS NULL
                 OR EndDate BETWEEN CAST (DateAdd(Day, 1 - Day(getDate()), getdate()) AS DATE) AND CAST (DateAdd(month, 1, DateAdd(Day, -Day(getDate()), getdate())) AS DATE))));

実行時間は約 10 分から約 1 時間になりました。これがなぜなのかについて何か提案はありますか? -cumulative' クエリごと。

4

3 に答える 3

4

これはかなり単純化された例だと思いますか?そのため、詳細をお伝えすることはできませんが、単純な答えは、クエリの累積部分が非累積部分よりも多くの作業を行っているということです。

この2つを比較してみてください...

SELECT ID,Name,StartDate,
       EndDate,
       rowTypeLabel AS Period
FROM   dbo.sicky

と...

SELECT ID,Name,StartDate,
       EndDate,
       rowTypeLabel AS Period
FROM   dbo.sicky
WHERE  EndDate IS NULL
       OR EndDate BETWEEN CAST (DateAdd(Day, 1 - Day(getDate()), getdate()) AS DATE) AND CAST (DateAdd(month, 1, DateAdd(Day, -Day(getDate()), getdate())) AS DATE))));

後者は、もっと時間がかかると思います。


また、ORビジネス ロジックの複数の部分をマージする条件は、オプティマイザにとって非常に難しい場合があります。これは、次の構造より効率的である可能性があることを意味します...

SELECT * FROM <non cumulative query>
UNION ALL
SELECT * FROM <cumulative query>
于 2012-01-23T15:06:29.527 に答える
1

ここで CROSS JOIN コンストラクトが必要な理由がわかりません。問題を混乱させているだけです。クエリを次のように書き直します。

SELECT ID, Name, StartDate, EndDate, 'Cumulative' AS Period
FROM   dbo.sicky
UNION ALL
SELECT ID, Name, StartDate, EndDate, 'Non-Cumulative' AS Period
FROM   dbo.sicky
WHERE EndDate IS NULL
    OR EndDate BETWEEN CAST (DateAdd(Day, 1 - Day(getDate()), getdate()) AS DATE) AND CAST (DateAdd(month, 1, DateAdd(Day, -Day(getDate()), getdate())) AS DATE))));

これは同等のはずですが、何をしているかをより明確に示しています。この UNION の最初の部分が以前のものであり、2 番目の部分が遅いと仮定すると、EndDate (または実際のクエリで同等のもの) が適切にインデックス化されておらず、過剰なスキャンが発生している可能性があります。より詳細な分析のために実行計画を投稿します。

于 2012-01-23T15:10:06.057 に答える
0

JOIN やサブクエリのない単純な SELECT の場合、10 分で 46000 行...多すぎるようです。StartDate と EndDate でインデックスを作成して有効にしたかどうかを確認します。もしそうなら、私は mwigdahl o Dems の回答に同意します。

于 2012-01-23T17:40:33.550 に答える