1

where句のすべての列にインデックスがあり、すべての列が結合されているにもかかわらず、実行に20分かかるクエリがあります。

SELECT DISTINCT skt.VCDRAWING_REG_NO, skb.NDRAWING_ORG_NO, skb.NDRAWING_ORG_REV_NO, skb.CAPPLY_START_DATE, skb.CAPPLY_END_DATE, skto.*
FROM SPM_ABS_TRANBASE skt
JOIN SPM_ABS_BASE skb
ON skt.NDRAWING_ORG_REV_NO = skb.NDRAWING_ORG_REV_NO
AND skt.NDRAWING_ORG_NO = skb.NDRAWING_ORG_NO
JOIN SPM_ABS_MODEL skm
ON skb.NDRAWING_ORG_REV_NO = skm.NDRAWING_ORG_REV_NO
AND skb.NDRAWING_ORG_NO = skm.NDRAWING_ORG_NO
JOIN SPM_ABS_TRANOPT skto
ON skt.NDRAWING_SYSTEM_NO = skto.NDRAWING_SYSTEM_NO
JOIN ModelImport mi
ON skm.CMODEL = mi.ModelCode
WHERE (skb.CAPPLY_START_DATE <= DATEADD(day, 2, GETDATE()) OR skb.CAPPLY_START_DATE IS NULL)
AND (skb.CAPPLY_END_DATE >= DATEADD(day, -2, GETDATE()) OR skb.CAPPLY_END_DATE IS NULL)

これが私のクエリプランです。

私を困惑させることの 1 つはこれです: 次の WHERE 句を追加すると、クエリは約 0.5 秒で返されます。

AND mi.ModelCode = '3FBK5'

well, duh, of course it gets much faster with thatつまり、ModelImport テーブルには 351 レコードしか含まれていないということです。つまり、上記のクエリを 351 個のクエリに分割し、それぞれに個別の ModelCode に対する独自の where 句を指定すると、クエリ結果の 100% を約 175 秒 (2.9 分) で取得できます。これは劇的に高速です。これは、広く開かれたクエリの何かが非常に非効率的であり、クエリ プランが悪いことを示しています。

これが追加された私のクエリプランです。AND mi.ModelCode = '3FBK5'

query planを表示した後、これを高速化する方法はありますか?

4

2 に答える 2

0

テーブルのスキーマとサイズがなければ、正確な答えを出すのは少し難しいですが、試してみるべきいくつかの更新を次に示します。

  • 個別の代わりにグループ化を使用する
  • 選択結果で * を使用しないでください (特に、distinct で) 代わりに、返す列の特定のリストを指定します
  • where句で「または」ステートメントを避ける(代わりにISNULLを使用することもできます)

これらの更新でクエリがどのように見えるかを次に示します (ただし、追加したい skto の他の列がいくつかある可能性があります)。

SELECT  skt.VCDRAWING_REG_NO, 
        skb.NDRAWING_ORG_NO, 
        skb.NDRAWING_ORG_REV_NO, 
        skb.CAPPLY_START_DATE, 
        skb.CAPPLY_END_DATE, 
        skto.NDRAWING_SYSTEM_NO
FROM    SPM_ABS_TRANBASE skt
        JOIN SPM_ABS_BASE skb ON 
            skt.NDRAWING_ORG_REV_NO = skb.NDRAWING_ORG_REV_NO
            AND skt.NDRAWING_ORG_NO = skb.NDRAWING_ORG_NO
        JOIN SPM_ABS_MODEL skm ON 
            skb.NDRAWING_ORG_REV_NO = skm.NDRAWING_ORG_REV_NO
            AND skb.NDRAWING_ORG_NO = skm.NDRAWING_ORG_NO
        JOIN SPM_ABS_TRANOPT skto ON 
            skt.NDRAWING_SYSTEM_NO = skto.NDRAWING_SYSTEM_NO
        JOIN ModelImport mi ON 
            skm.CMODEL = mi.ModelCode
WHERE   ISNULL(skb.CAPPLY_START_DATE, DATEADD(day, 2, GETDATE())) <= DATEADD(day, 2, GETDATE())
        AND ISNULL(skb.CAPPLY_END_DATE,DATEADD(day, -2, GETDATE())) >= DATEADD(day, -2, GETDATE())
GROUP BY skt.VCDRAWING_REG_NO, 
        skb.NDRAWING_ORG_NO, 
        skb.NDRAWING_ORG_REV_NO, 
        skb.CAPPLY_START_DATE, 
        skb.CAPPLY_END_DATE,
        skto.NDRAWING_SYSTEM_NO
于 2019-08-16T17:55:12.717 に答える