クエリの実行が非常に遅いですが、さらに改善する方法はありますか?


9

次のクエリがありSUMますが、関数呼び出しが多いため、クエリの実行が遅すぎます。データベースに多数のレコードがあり、それぞれについて、現在の年と昨年(過去30日間、過去90日間、過去365日間)のレポートを取得したいと思います。

SELECT 
    b.id as [ID]
    ,d.[Title] as [Title]
    ,e.Class as [Class]

    ,Sum(CASE WHEN a.DateCol >= DATEADD(MONTH,-1,GETDATE()) THEN a.col1 ELSE 0 END) as [Current - Last 30 Days Col1]
    ,Sum(CASE WHEN a.DateCol >= DATEADD(MONTH,-1,GETDATE()) THEN a.col2 ELSE 0 END) as [Current - Last 30 Days Col2]

    ,Sum(CASE WHEN a.DateCol >= DATEADD(QUARTER,-1,GETDATE()) THEN a.col1 ELSE 0 END) as [Current - Last 90 Days Col1]
    ,Sum(CASE WHEN a.DateCol >= DATEADD(QUARTER,-1,GETDATE()) THEN a.col2 ELSE 0 END) as [Current - Last 90 Days Col2]

    ,Sum(CASE WHEN a.DateCol >= DATEADD(YEAR,-1,GETDATE()) THEN a.col1 ELSE 0 END) as [Current - Last 365 Days Col1]
    ,Sum(CASE WHEN a.DateCol >= DATEADD(YEAR,-1,GETDATE()) THEN a.col2 ELSE 0 END) as [Current - Last 365 Days Col2]

    ,Sum(CASE WHEN a.DateCol >= DATEADD(MONTH,-13,GETDATE()) and a.DateCol <= DATEADD(MONTH,-12,GETDATE()) THEN a.col1 ELSE 0 END) as [Last year - Last 30 Days Col1]
    ,Sum(CASE WHEN a.DateCol >= DATEADD(MONTH,-13,GETDATE()) and a.DateCol <= DATEADD(MONTH,-12,GETDATE()) THEN a.col2 ELSE 0 END) as [Last year - Last 30 Days Col2]

    ,Sum(CASE WHEN a.DateCol >= DATEADD(QUARTER,-5,GETDATE()) and a.DateCol <= DATEADD(QUARTER,-4,GETDATE()) THEN a.col1 ELSE 0 END) as [Last year - Last 90 Days Col1]
    ,Sum(CASE WHEN a.DateCol >= DATEADD(QUARTER,-5,GETDATE()) and a.DateCol <= DATEADD(QUARTER,-4,GETDATE()) THEN a.col2 ELSE 0 END) as [Last year - Last 90 Days Col2]

    ,Sum(CASE WHEN a.DateCol >= DATEADD(YEAR,-2,GETDATE()) and a.DateCol <= DATEADD(YEAR,-1,GETDATE()) THEN a.col1 ELSE 0 END) as [Last year - Last 365 Days Col1]
    ,Sum(CASE WHEN a.DateCol >= DATEADD(YEAR,-2,GETDATE()) and a.DateCol <= DATEADD(YEAR,-1,GETDATE()) THEN a.col2 ELSE 0 END) as [Last year - Last 365 Days Col2]


    FROM 
    tb1 a
INNER JOIN 
    tb2 b on a.id=b.fid and a.col3 = b.col4
INNER JOIN 
    tb3 c on b.fid = c.col5
INNER JOIN       
    tb4 d on c.id = d.col6
INNER JOIN 
    tb5 e on c.col7 = e.id
GROUP BY
    b.id, d.Title, e.Class

より速く実行するためにクエリをどのように改善できるかについて誰かが何か考えを持っていますか?

編集:私はDATEADD関数呼び出しをwhereステートメントに移動し、最初の2年を最初にロードしてから列でフィルタリングすることを勧められましたが、提案された回答が実行されて機能するかどうかはわかりません.https:// stackoverflowで見つけることができます。 com / a / 59944426/12536284

上記のソリューションに同意する場合は、現在のクエリにどのように適用できるかを教えてください。

参考までに、私はこのSPをC#のEntity Framework(DB-First)で使用しています。

var result = MyDBEntities.CalculatorSP();

4
あなたの実行計画を見せて...
Dale K

1
何でも -クエリを遅くすることができるものです
Fabio


2
繰り返しになりますが、実行計画を投稿してください。
SQL警察

2
まだ私たちは見ていませんExecution Plan。投稿してください
アルンパラニサミー

回答:


10

すでに述べたように、この場合、実行計画は非常に役立ちます。表示された内容に基づいてtb1 (a)、から合計15列の12列を抽出したようです。結合なしでクエリを実行してtb1、クエリが期待どおりに機能しているかどうかを確認することができます。あなたのSUM関数呼び出しには何も問題がないように見えるので、私はあなたの結合に問題があると思います。次のようにすることをお勧めします。あなたが最後のインスタンスのために参加を除くことによって開始、できる INNER JOIN tb5 e on c.col7 = e.idなど、それの関連するすべての利用状況e.Class as [Class]e.Classステートメントでグループ内。完全に除外するつもりはありません。これは、クエリがより適切に実行され、予想通り、最後の結合の代わりに一時テーブルを回避策として使用できる場合に、問題がそれに関するものかどうかを確認するためのテストです、 このようなもの:

SELECT *
INTO #Temp
FROM
  (
     select * from tb5
  ) As tempTable;

SELECT 
    b.id as [ID]
    ,d.[Title] as [Title]
    ,e.Class as [Class]

    -- SUM Functions

FROM 
    tb1 a
INNER JOIN 
    tb2 b on a.id=b.fid and a.col3 = b.col4
INNER JOIN 
    tb3 c on b.fid = c.col5
INNER JOIN       
    tb4 d on c.id = d.col6
INNER JOIN 
    #Temp e on c.col7 = e.id
GROUP BY
    b.id, d.Title, e.Class

実際、一時テーブルは、SQL Serverに一時的に存在するテーブルです。一時テーブルは、複数回アクセスされる即時結果セットを格納するのに役立ちます。詳細については、https://www.sqlservertutorial.net/sql-server-basics/sql-server-temporary-tables/をご覧ください。 また、こちらhttps://codingsight.com/introduction-to-temporary-tables-in -SQLサーバー/

また、ストアドプロシージャを使用している場合はをに設定するNOCOUNTON、ネットワークトラフィックが大幅に削減されるため、パフォーマンスが大幅に向上することを強くお勧めします。

SET NOCOUNT ON
SELECT *
INTO #Temp
-- The rest of code

基づいて、この

SET NOCOUNT ONは、T-SQLクエリステートメントの影響を受ける行数を示すメッセージを防止するsetステートメントです。これは、ストアドプロシージャおよびトリガー内で使用され、影響を受ける行のメッセージが表示されないようにします。ストアドプロシージャ内でSET NOCOUNT ONを使用すると、ストアドプロシージャのパフォーマンスを大幅に向上させることができます。


1
テーブルに全体tb5をコピー#Tempして一時テーブルに結合tb5すると、直接結合するよりも速く機能する理由を説明できますか?確かにそれらには同じデータが含まれています(#Tempインデックスがに存在する場合は、インデックスが欠落している可能性がありますtb5)。なぜこれがより効率的であるのか本当に理解できません(すべてのデータをコピーし結合する方が効率が悪いはずです)。
ジグ

2
@zigこの場合は正しいですが、がtb5別のサーバーにある場合はどうなりますか?この場合、一時テーブルを使用する方が、別のサーバーに直接結合するよりも明らかに高速です。これは、何か変更があったかどうかをテストして確認するための提案でした。過去に同様の状況がありましたが、幸いにも、この場合も一時テーブルがOPに役立ちました。
Salah Akbari

2

最善の方法は、テーブル変数/ハッシュテーブルに挿入することです(行数が少ない場合はテーブル変数を使用するか、行数がかなり多い場合はハッシュテーブルを使用します)。次に、集計を更新し、最後にテーブル変数またはハッシュテーブルから選択します。クエリプランを調べる必要があります。

DECLARE @MYTABLE TABLE (ID INT, [Title] VARCHAR(500), [Class] VARCHAR(500),
[Current - Last 30 Days Col1] INT, [Current - Last 30 Days Col2] INT,
[Current - Last 90 Days Col1] INT,[Current - Last 90 Days Col2] INT,
[Current - Last 365 Days Col1] INT, [Current - Last 365 Days Col2] INT,
[Last year - Last 30 Days Col1] INT, [Last year - Last 30 Days Col2] INT,
[Last year - Last 90 Days Col1] INT, [Last year - Last 90 Days Col2] INT,
[Last year - Last 365 Days Col1] INT, [Last year - Last 365 Days Col2] INT)



INSERT INTO @MYTABLE(ID, [Title],[Class], 
[Current - Last 30 Days Col1], [Current - Last 30 Days Col2],
[Current - Last 90 Days Col1], [Current - Last 90 Days Col2],
[Current - Last 365 Days Col1], [Current - Last 365 Days Col2],
[Last year - Last 30 Days Col1], [Last year - Last 30 Days Col2],
[Last year - Last 90 Days Col1], [Last year - Last 90 Days Col2],
[Last year - Last 365 Days Col1], [Last year - Last 365 Days Col2]
  )
SELECT    b.id  ,d.[Title] ,e.Class ,0,0,0,0,0,0,0,0,0,0,0,0        
FROM     tb1 a
INNER JOIN   tb2 b on a.id=b.fid and a.col3 = b.col4
INNER JOIN   tb3 c on b.fid = c.col5
INNER JOIN   tb4 d on c.id = d.col6
INNER JOIN  tb5 e on c.col7 = e.id
GROUP BY b.id, d.Title, e.Class

UPDATE T 
SET [Current - Last 30 Days Col1]=K.[Current - Last 30 Days Col1] , 
[Current - Last 30 Days Col2]    =K.[Current - Last 30 Days Col2],
[Current - Last 90 Days Col1]    = K.[Current - Last 90 Days Col1], 
[Current - Last 90 Days Col2]    =K.[Current - Last 90 Days Col2] ,
[Current - Last 365 Days Col1]   =K.[Current - Last 365 Days Col1], 
[Current - Last 365 Days Col2]   =K.[Current - Last 365 Days Col2],
[Last year - Last 30 Days Col1]  =K.[Last year - Last 30 Days Col1],
 [Last year - Last 30 Days Col2] =K.[Last year - Last 30 Days Col2],
[Last year - Last 90 Days Col1]  =K.[Last year - Last 90 Days Col1], 
[Last year - Last 90 Days Col2]  =K.[Last year - Last 90 Days Col2],
[Last year - Last 365 Days Col1] =K.[Last year - Last 365 Days Col1],
 [Last year - Last 365 Days Col2]=K.[Last year - Last 365 Days Col2]
    FROM @MYTABLE T JOIN 
     (
SELECT 
    b.id as [ID]
    ,ISNULL(Sum(CASE WHEN a.DateCol >= DATEADD(MONTH,-1,GETDATE()) THEN a.col1 ELSE 0 END),0) as [Current - Last 30 Days Col1]
    ,ISNULL(Sum(CASE WHEN a.DateCol >= DATEADD(MONTH,-1,GETDATE()) THEN a.col2 ELSE 0 END),0) as [Current - Last 30 Days Col2]

    ,ISNULL(Sum(CASE WHEN a.DateCol >= DATEADD(QUARTER,-1,GETDATE()) THEN a.col1 ELSE 0 END),0) as [Current - Last 90 Days Col1]
    ,ISNULL(Sum(CASE WHEN a.DateCol >= DATEADD(QUARTER,-1,GETDATE()) THEN a.col2 ELSE 0 END),0) as [Current - Last 90 Days Col2]

    ,ISNULL(Sum(CASE WHEN a.DateCol >= DATEADD(YEAR,-1,GETDATE()) THEN a.col1 ELSE 0 END),0) as [Current - Last 365 Days Col1]
    ,ISNULL(Sum(CASE WHEN a.DateCol >= DATEADD(YEAR,-1,GETDATE()) THEN a.col2 ELSE 0 END),0) as [Current - Last 365 Days Col2]

    ,ISNULL(Sum(CASE WHEN a.DateCol >= DATEADD(MONTH,-13,GETDATE()) and a.DateCol <= DATEADD(MONTH,-12,GETDATE()) THEN a.col1 ELSE 0 END),0) as [Last year - Last 30 Days Col1]
    ,ISNULL(Sum(CASE WHEN a.DateCol >= DATEADD(MONTH,-13,GETDATE()) and a.DateCol <= DATEADD(MONTH,-12,GETDATE()) THEN a.col2 ELSE 0 END),0) as [Last year - Last 30 Days Col2]

    ,ISNULL(Sum(CASE WHEN a.DateCol >= DATEADD(QUARTER,-5,GETDATE()) and a.DateCol <= DATEADD(QUARTER,-4,GETDATE()) THEN a.col1 ELSE 0 END),0) as [Last year - Last 90 Days Col1]
    ,ISNULL(Sum(CASE WHEN a.DateCol >= DATEADD(QUARTER,-5,GETDATE()) and a.DateCol <= DATEADD(QUARTER,-4,GETDATE()) THEN a.col2 ELSE 0 END),0) as [Last year - Last 90 Days Col2]

    ,ISNULL(Sum(CASE WHEN a.DateCol >= DATEADD(YEAR,-2,GETDATE()) and a.DateCol <= DATEADD(YEAR,-1,GETDATE()) THEN a.col1 ELSE 0 END),0) as [Last year - Last 365 Days Col1]
    ,ISNULL(Sum(CASE WHEN a.DateCol >= DATEADD(YEAR,-2,GETDATE()) and a.DateCol <= DATEADD(YEAR,-1,GETDATE()) THEN a.col2 ELSE 0 END),0) as [Last year - Last 365 Days Col2]
    FROM     tb1 a
INNER JOIN   tb2 b on a.id=b.fid and a.col3 = b.col4
INNER JOIN   tb3 c on b.fid = c.col5
INNER JOIN   tb4 d on c.id = d.col6
INNER JOIN  tb5 e on c.col7 = e.id
GROUP BY    b.id
) AS K ON T.ID=K.ID


SELECT *
FROM @MYTABLE

0

私はtb1が(tb2、tb3、tb4、tb5に対して)大きなテーブルであると想定しています。

その場合、そのテーブルの選択を(WHERE句を使用して)制限することは、ここでは理にかなっています。

tb2、tb3、tb4、およびtb5との結合によって必要な行が数パーセントに減少するなど、tb1のごく一部のみが使用される場合、結合で使用する列にテーブルのインデックスが作成されているかどうかを確認する必要があります。

tb1の大部分が使用される場合、tb2、tb3、tb4、およびtb5に結合する前に、結果をグループ化することは理にかなっています。以下はその例です。

SELECT 
    b.id as [ID]
    ,d.[Title] as [Title]
    ,e.Class as [Class]
    ,SUM(a.[Current - Last 30 Days Col1]) AS [Current - Last 30 Days Col1]
    ,SUM(a.[Current - Last 30 Days Col2]) AS [Current - Last 30 Days Col2]
    ,SUM(a.[Current - Last 90 Days Col1]) AS [Current - Last 90 Days Col1]
    -- etc.
    FROM (
      SELECT a.id, a.col3

      ,Sum(CASE WHEN a.DateCol >= DATEADD(MONTH,-1,GETDATE()) THEN a.col1 ELSE 0 END) as [Current - Last 30 Days Col1]
      ,Sum(CASE WHEN a.DateCol >= DATEADD(MONTH,-1,GETDATE()) THEN a.col2 ELSE 0 END) as [Current - Last 30 Days Col2]

      ,Sum(CASE WHEN a.DateCol >= DATEADD(QUARTER,-1,GETDATE()) THEN a.col1 ELSE 0 END) as [Current - Last 90 Days Col1]
      ,Sum(CASE WHEN a.DateCol >= DATEADD(QUARTER,-1,GETDATE()) THEN a.col2 ELSE 0 END) as [Current - Last 90 Days Col2]

      ,Sum(CASE WHEN a.DateCol >= DATEADD(YEAR,-1,GETDATE()) THEN a.col1 ELSE 0 END) as [Current - Last 365 Days Col1]
      ,Sum(CASE WHEN a.DateCol >= DATEADD(YEAR,-1,GETDATE()) THEN a.col2 ELSE 0 END) as [Current - Last 365 Days Col2]

      ,Sum(CASE WHEN a.DateCol >= DATEADD(MONTH,-13,GETDATE()) and a.DateCol <= DATEADD(MONTH,-12,GETDATE()) THEN a.col1 ELSE 0 END) as [Last year - Last 30 Days Col1]
      ,Sum(CASE WHEN a.DateCol >= DATEADD(MONTH,-13,GETDATE()) and a.DateCol <= DATEADD(MONTH,-12,GETDATE()) THEN a.col2 ELSE 0 END) as [Last year - Last 30 Days Col2]

      ,Sum(CASE WHEN a.DateCol >= DATEADD(QUARTER,-5,GETDATE()) and a.DateCol <= DATEADD(QUARTER,-4,GETDATE()) THEN a.col1 ELSE 0 END) as [Last year - Last 90 Days Col1]
      ,Sum(CASE WHEN a.DateCol >= DATEADD(QUARTER,-5,GETDATE()) and a.DateCol <= DATEADD(QUARTER,-4,GETDATE()) THEN a.col2 ELSE 0 END) as [Last year - Last 90 Days Col2]

      ,Sum(CASE WHEN a.DateCol >= DATEADD(YEAR,-2,GETDATE()) and a.DateCol <= DATEADD(YEAR,-1,GETDATE()) THEN a.col1 ELSE 0 END) as [Last year - Last 365 Days Col1]
      ,Sum(CASE WHEN a.DateCol >= DATEADD(YEAR,-2,GETDATE()) and a.DateCol <= DATEADD(YEAR,-1,GETDATE()) THEN a.col2 ELSE 0 END) as [Last year - Last 365 Days Col2]

      FROM  tb1 a
      WHERE a.DateCol >= DATEADD(YEAR,-2,GETDATE())
      GROUP BY a.id, a.col3
    ) AS a
INNER JOIN 
    tb2 b on a.id=b.fid and a.col3 = b.col4
INNER JOIN 
    tb3 c on b.fid = c.col5
INNER JOIN       
    tb4 d on c.id = d.col6
INNER JOIN 
    tb5 e on c.col7 = e.id
GROUP BY
    b.id, d.Title, e.Class

最初に実行プランを表示してから、インデックスの作成と統計の再作成について決定する方がはるかに良いでしょう。
SQLポリス

私の投稿が理由の説明なしにマイナスのスコアを獲得するのは本当に嫌いです。もちろん、パフォーマンスの問題の核心に到達するには、実行計画を検査する必要があることにも同意します。そうは言っても、クエリに関連するすべての外部キーのインデックスをチェックすることについては、私の推奨を支持します。
Gert-Jan

1
あなたは知らずに何かを「想定」します。だからあなたは未知に基づいて答えを投稿します。したがって、反対票を投じます。OPに実行計画を投稿して質問を改善するように指示することをお勧めします。
SQL警察

私が書いたのはそれだけではありません。個人的には、私が単に反対するときではなく、答えが悪いか間違っている場合にのみ反対投票します。しかし、応答してくれてありがとう。
Gert-Jan

ある意味、それが正しいことをどのように証明できるのか、それは間違っていますか?
SQL警察


0

このような計算を最適化するには、いくつかの値を事前に計算することを検討してください。事前計算の考え方は、読み取りまたは続行する必要がある行の数を減らすことです。

これを実現する1つの方法は、インデックス付きビューを使用して、エンジンが単独で計算を行うようにすることです。このタイプのビューにはいくつかの制限があるため、単純なテーブルを作成して、代わりに計算を実行することになります。基本的には、ビジネスニーズによって異なります。

したがって、以下の例では、RowIDおよびRowDatetime列を含むテーブルを作成し、100万行を挿入しています。インデックス付きビューを使用して1日あたりのエンティティをカウントしているので、年間100万行をクエリする代わりに、年間365行をクエリしてこれらのメトリックをカウントします。

DROP TABLE IF EXISTS [dbo].[DataSource];
GO

CREATE TABLE [dbo].[DataSource]
(
    [RowID] BIGINT IDENTITY(1,1) PRIMARY KEY
   ,[RowDateTime] DATETIME2
);

GO

DROP VIEW IF EXISTS [dbo].[vw_DataSource];
GO

CREATE VIEW [dbo].[vw_DataSource] WITH SCHEMABINDING
AS
SELECT YEAR([RowDateTime]) AS [Year]
      ,MONTH([RowDateTime]) AS [Month]
      ,DAY([RowDateTime]) AS [Day]
      ,COUNT_BIG(*) AS [Count]
FROM [dbo].[DataSource]
GROUP BY YEAR([RowDateTime])
        ,MONTH([RowDateTime])
        ,DAY([RowDateTime]);
GO

CREATE UNIQUE CLUSTERED INDEX [IX_vw_DataSource] ON [dbo].[vw_DataSource]
(
    [Year] ASC,
    [Month] ASC,
    [Day] ASC
);

GO

DECLARE @min bigint, @max bigint
SELECT @Min=1 ,@Max=1000000

INSERT INTO [dbo].[DataSource] ([RowDateTime])
SELECT TOP (@Max-@Min+1) DATEFROMPARTS(2019,  1.0 + floor(12 * RAND(convert(varbinary, newid()))), 1.0 + floor(28 * RAND(convert(varbinary, newid())))          )       
FROM master..spt_values t1 
CROSS JOIN master..spt_values t2

GO


SELECT *
FROM [dbo].[vw_DataSource]


SELECT SUM(CASE WHEN DATEFROMPARTS([Year], [Month], [Day]) >= DATEADD(MONTH,-1,GETDATE()) THEN [Count] ELSE 0 END) as [Current - Last 30 Days Col1]
      ,SUM(CASE WHEN DATEFROMPARTS([Year], [Month], [Day]) >= DATEADD(QUARTER,-1,GETDATE()) THEN [Count] ELSE 0 END) as [Current - Last 90 Days Col1]
      ,SUM(CASE WHEN DATEFROMPARTS([Year], [Month], [Day]) >= DATEADD(YEAR,-1,GETDATE()) THEN [Count] ELSE 0 END) as [Current - Last 365 Days Col1]
FROM [dbo].[vw_DataSource];

このようなソリューションが成功するかどうかは、データの分散方法と行数に大きく依存します。たとえば、年の各日に1日に1つのエントリがある場合、ビューとテーブルの行の一致は同じになるため、I / O操作は削減されません。

また、上記はデータを具体化して読み取る例です。あなたの場合、ビュー定義にさらに列を追加する必要があるかもしれません。


0

ルックアップテーブルの「Dates」テーブルを使用して、DatesIdのインデックスとデータを結合します。履歴データを参照したい場合は、日付をフィルターとして使用します。結合は高速であるため、DatesIdがクラスター化されたプライマリインデックス(プライマリキー)としてフィルタリングされます。データテーブルの日付列(含まれる列として)も追加します。

日付テーブルには次の列があります。

DatesId、Date、Year、Quarter、YearQuarter、MonthNum、MonthNameShort、YearWeek、WeekNum、DayOfYear、DayOfMonth、DayNumOfWeek、DayName

データ例:20310409 2031-04-09 2031 2 2031-Q2 4 4月2031_15 15 99 9 3水曜日

これのcsvが必要な場合は、PMしてデータベースにインポートできますが、このようなものをオンラインで簡単に見つけて、自分で作成できると確信しています。

ID列も追加して、日付ごとに整数を取得できるようにします。これにより、操作が少し簡単になりますが、必須ではありません。

SELECT * FROM dbo.dates where dateIndex BETWEEN (getDateIndexDate(getDate())-30 AND getDateIndexDate(getDate())+0) --30 days ago

これにより、特定の期間に簡単に戻ることができます。これについて独自のビューを作成するのは非常に簡単です。もちろん、ROW_NUMBER()関数を使用して、数年、数週間など、これを行うこともできます。

必要な日付範囲を取得したら、データに参加します。非常に速く動作します!


0

常に月数に基づいて値をグループ化しているため、最初にfrom句のサブクエリで月ごとにグループ化します。これは、一時テーブルの使用に似ています。これが実際にクエリを高速化するかどうかは不明です。

SELECT f.id, f.[Title], f.Class,
    SUM(CASE WHEN f.MonthDiff = 1 THEN col1 ELSE 0 END) as [Current - Last 30 Days Col1],
    -- etc
FROM (
    SELECT 
        b.id,
        d.[Title],
        e.Class,
        DateDiff(Month, a.DateCol, GETDATE()) as MonthDiff,
        Sum(a.col1) as col1,
        Sum(a.col2) as col2
    FROM  tb1 a
    INNER JOIN tb2 b on a.id = b.fid and a.col3 = b.col4
    INNER JOIN tb3 c on b.fid = c.col5
    INNER JOIN tb4 d on c.id = d.col6
    INNER JOIN tb5 e on c.col7 = e.id
    WHERE a.DateCol between DATEADD(YEAR,-2,GETDATE() and GETDATE()
    GROUP BY b.id, d.Title, e.Class, DateDiff(Month,  a.DateCol, GETDATE())
) f
group by f.id, f.[Title], f.Class

-2

SQLクエリの速度を向上させるには、インデックスを追加する必要があります。結合されたテーブルごとに、1つのインデックスを追加する必要があります。

このoracleのコード例のように:

CREATE INDEX supplier_idx
ON supplier (supplier_name);

これは悪い提案ではありません。OPから、一時テーブルがインデックスなしで作成されていることがわかります-INNER JOIN #Temp e on c.col7 =e.id。答えに改善の余地はありますが、一斉に投票するべきではないと思います。特に新しいユーザーのために。
smoore4

@ smoore4同意します。明確な引数なしでの反対投票のこのオプションは削除する必要があります。この機能には大きな誤用があります
Greggz
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.