他の人が作成したSSRSレポートで使用されているこのクエリがあります。左結合が問題の原因です。私がインナー・ジョイントに変更すると、約15秒で結果が得られます(正しい結果ではありません)。 Left Joinを使用すると、20分後にクエリがキャンセルされます。 Budgets.ProfessionalsとTransactions.Professionalsの両方にインデックスを追加しましたが、パフォーマンスは変わりません。クエリを書き換え、左結合を使用しない方法はありますか?このクエリでは、左結合にはどのような選択肢がありますか?
SELECT
profs.ProfName as orig
,profs.Initials
,DATEPART(year, TransDate) as [Year]
,SUM(CASE WHEN IsFlatFee = 'Y' OR COALESCE(MT.Admin, 'N') = 'Y'
THEN 0.0
ELSE Units * (aph.assignedpercent/100) * isnull(B.rate, 0.0)
END) AS ctp
,SUM(CASE WHEN IsFlatFee = 'Y' OR COALESCE(MT.Admin, 'N') = 'Y'
THEN 0
ELSE Units
END * (aph.assignedpercent/100)) AS worked_hours
,SUM(Value * (aph.assignedpercent/100)) AS worked_value
, 0 AS billed_hours
,0 AS billed_value
,0 AS billed_netamt
, 0.0 as paid
, 0.0 as wo
FROM Transactions Trans
INNER JOIN Matters Matts ON Trans.matters = Matts.matters
INNER JOIN MatterTypes MT ON Matts.mattertype = MT.mattertypesdesc
and MT.Admin <> 'Y'
INNER JOIN Components Comps ON Comps.components = Trans.components
and Comps.CompType = 'F'
INNER JOIN AssignedProfsHistory APH on APH.Matters = Trans.Matters
and APH.AssignedType = 'Originating'
and Trans.TransDate between APH.EffectiveDate and
ISNULL(EndDate,'12/31/2099')
INNER JOIN Professionals profs on profs.Professionals = APH.Professionals
and profs.ProfType = 'Member'
and profs.IsActive = 'Y'
and profs.IsBillable = 'Y'
**LEFT join** (SELECT Budgets.Professionals as timekeeper, Budgets.Amount as
rate, Budgets.PeriodDate
FROM Matters Matts
INNER JOIN Budgets ON Matts.matters = Budgets.matters
and cast(Budgets.PeriodDate as Date) <= '2017-12-31'
AND MONTH('2017-12-31') = MONTH(Budgets.PeriodDate)
WHERE Matts.MatterID = '99999-99.003') as B
*on B.timekeeper = Trans.Professionals*
and YEAR(B.PeriodDate) = DATEPART(year, TransDate)
WHERE cast(transdate as DATE) between dateadd(day, 1, DATEADD(year, -3,
'2017-12-31')) and '2017-12-31'
GROUP BY profs.ProfName, profs.Initials, DATEPART(year, TransDate)
誰もこのような小さな情報で助けてくれる可能性はほとんどありません。ここに含まれるすべてのテーブルの索引を含むテーブル定義と、およその行数を見る必要があります。さらに、実行計画は役立ちますが、可能ではない可能性のあるクエリを完了することができないためです。 –
なぜ 'cast(Budgets.PeriodDate as Date)'という名前でキャストしているのか、なぜなら、 'MONTH(Budgets.PeriodDate)'キャストのない同じフィールドで日付関数を実行するような、/joinはどこのインデックスの使用も無効にすることができるので、関数を実行することには常に注意するべきです。そうでなければ、ショーンは言った。 –
私はLEFT JOINされたテーブルのインデックスを使用していないと思います。おそらく、Budgets.PeriodDateのインデックスがありますが、列(および関連するインデックス)を使用しようとする前に、CASTを実行しています。その時点で、オプティマイザは新しい値がインデックスと同じであるという考えをもはや持っていません。なぜなら、そうでないかもしれないからです。私たちは、あなたのテーブル構造、インデックス、および推定された実行計画を見なければなりません(なぜなら、Seanはあなたが実際のものを持っていないと言っていたからです)。 – indiri