我有兩個物理表:
notTempBaseLine 有 50k 記錄(版本索引,SrcDimension2_)
notTempTrans 有 400k 記錄(BaseLineVersion 上的索引,Dimension2_)
我有一個查詢,執行 2 小時
select
BaseLine.RECID,
notTempTrans.recid
from notTempBaseLine baseLine
join notTempTrans
on
baseLine.Version = notTempTrans.baseLineVersion
and
(
baseLine.SrcDimension2_ = ''
or
(baseLine.SrcDimension2_ = '""' and notTempTrans.Dimension2_ = '')
or
(baseLine.SrcDimension2_ = '!""' and notTempTrans.Dimension2_ '')
or
baseLine.SrcDimension2_ = notTempTrans.Dimension2_
)
如果我使用“ORs”組中的任何一個條件運行查詢 - 它執行 1 秒,但是當我運行(A 或 B 或 C 或 D)時 - 會發生一些奇怪的事情并且查詢執行 2 小時。
任何想法,發生了什么以及我該如何解決?我不能用 UNION 替換 OR,因為在實際查詢中我有幾個相同的 OR 條件塊(或塊的 OR AND 塊的 OR AND ...)
以下是計劃:
https://www.brentozar.com/pastetheplan/?id=rkOr1oc85
https://www.brentozar.com/pastetheplan/?id=rJQKyo98c
uj5u.com熱心網友回復:
看起來您可以將條件存盤在臨時表中并對它們進行條件連接。我希望這有幫助。最后的加入可能不是最好的。您可以嘗試將最后一個連接轉換為 where 子句。
WITH
condition_mapping
AS
(
SELECT tbl.* FROM (VALUES
(NULL, NULL)
, ( '', NULL)
, ( '', '')
, ( '', '""')
, ( '', '!""')
) tbl ([NT_Dimension2_], [BL_Dimension2_])
)
SELECT
[BaseLine].[RECID]
, [notTempTrans].[recid]
FROM
[notTempBaseLine] AS [baseLine]
INNER JOIN [notTempTrans] ON [baseLine].[Version] = [notTempTrans].[baseLineVersion]
INNER JOIN condition_mapping AS cm
ON ISNULL(cm.[BL_Dimension2_], [baseLine].[Dimension2_]) = [baseLine].[Dimension2_]
AND ISNULL(cm.[NT_Dimension2_], [notTempTrans].[Dimension2_]) = [notTempTrans].[Dimension2_]
AND (CASE WHEN cm.[BL_Dimension2_] IS NULL AND cm.[NT_Dimension2_] IS NULL THEN [baseLine].[Dimension2_] ELSE [notTempTrans].[Dimension2_] END) = [notTempTrans].[Dimension2_];
uj5u.com熱心網友回復:
我在您的查詢計劃中看到了聚集索引掃描。根據您的陳述,似乎正在掃描兩個表以查找適當的資料。這使我相信您的索引設定不正確,您可能會錯過減少搜索空間的機會。我建議向表中添加索引(見下文),以使用 where 陳述句中定義的相等比較操作。
PS:將您的相等比較移到 where 陳述句而不是 join,它聞起來很香。
select
BaseLine.RECID,
notTempTrans.recid
from notTempBaseLine baseLine
join notTempTrans
on
baseLine.Version = notTempTrans.baseLineVersion
WHERE
baseLine.SrcDimension2_ = ''
or
(baseLine.SrcDimension2_ = '""' and notTempTrans.Dimension2_ = '')
or
(baseLine.SrcDimension2_ = '!""' and notTempTrans.Dimension2_ <> '')
or
baseLine.SrcDimension2_ = notTempTrans.Dimension2_
祝你好運。
CREATE NONCLUSTERED INDEX [notTempBaseLine_SrcDimension2__Version] ON [dbo].[notTempBaseLine]
(
[SrcDimension2_] ASC, [Version] ASC
) INCLUDE([RECID]) WITH (ONLINE = OFF, MAXDOP=0);
GO
CREATE NONCLUSTERED INDEX [notTempTrans_Dimension2_BaseLineVersion] ON [dbo].[notTempTrans]
(
[Dimension2_] ASC, [BaseLineVersion] ASC
) INCLUDE([recid]) WITH (ONLINE = OFF, MAXDOP=0);
GO
uj5u.com熱心網友回復:
試試這個:
select BaseLine.RECID,
notTempTrans.recid
from notTempBaseLine AS baseLine
join notTempTrans
on baseLine.Version = notTempTrans.baseLineVersion
and
(
baseLine.SrcDimension2_ IN ('', notTempTrans.Dimension2_)
or
(notTempTrans.Dimension2_ = '' AND (baseLine.SrcDimension2_ = '""' OR baseLine.SrcDimension2_ = '!""'))
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/478225.html
