Date

IsNull Alternatives 的情況?

  • January 6, 2018

有沒有辦法優化這個查詢,其中使用了幾個與日期相關的 IsNull?不幸的是,查詢速度很慢,實際上我沒有膠水,如何讓它更快。

case
when IsNull(A.TD, '1900-01-01') > IsNull(B.TD, '1900-01-01') then IsNull(A.TD, '1900-01-01')
when IsNull(A.TD, '1900-01-01') < IsNull(B.TD, '1900-01-01') then IsNull(B.TD, '1900-01-01')
when IsNull(A.TD, '1900-01-01') = IsNull(B.TD, '1900-01-01') then S.TE end as DZ

謝謝你。

正如sp_BlitzErik在他的評論中指出的那樣,他有一篇關於這個主題的優秀文章。

然而,他的查詢是一個特例,他所做的一些事情只是因為他想要一個COUNT. 由於您僅從您的WHERE子句中呈現一個表達式,因此我們無法對您查詢的其餘部分做出任何特定假設。無論如何,我確實建議您查看 Erik 的文章。這很好。

鑑於您提出的內容,我提出以下建議:

case
when A.TD IS NULL and B.TD IS NULL THEN S.TE
when A.TD IS NULL and '1900-01-01' > B.TD THEN '1900-01-01'
when A.TD IS NULL and '1900-01-01' < B.TD THEN B.TD
when A.TD IS NULL and '1900-01-01' = B.TD THEN S.TE
when A.TD > '1900-01-01' and B.TD IS NULL THEN A.TD
when A.TD < '1900-01-01' and B.TD IS NULL THEN '1900-01-01'
when A.TD = '1900-01-01' and B.TD IS NULL THEN S.TE
when A.TD > B.TD then A.TD
when A.TD < B.TD then B.TD
when A.TD = B.TD then S.TE end as DZ

基本上ISNULL(A, n) = m可以分為兩部分:

(   (A IS NULL and n = m)
OR A = m
)

如您所知,SQL 在技術上使用三元邏輯 - 表達式可以是 TRUE、FALSE 或 NULL。對於由 連接的兩個表達式OR計算為 TRUE,其中一個必須為真 - 另一個可以是 FALSE 或 NULL,沒關係。

因此,如果 A 不為 NULL,則第一個表達式將始終為 FALSE,而第二個表達式的結果(只要 m 不為 NULL,它就不會為 NULL)將確定該對的值。

並且,如果 ANULL,則第二個表達式將為 NULL,而第一個表達式(只要 n 和 M 都不是 NULL,則不會為 NULL)確定該對的值。

由於我們正在查看兩個表達式的多重比較,因此事情變得有點複雜,但不一定是難以管理的。

請注意,您也許可以簡化表達式。如果您的日期永遠不會低於硬編碼日期,那麼您不需要查看是否A.TDB.TD小於該日期。

您可能還想重新排列各個WHEN子句。在不損害可維護性的情況下,我傾向於將代表最有可能發生的子句放在首位;在您的情況下,如果 NULL 很少見,那可能是最後三個檢查。我不確定查詢優化器是否按照它們呈現的順序執行檢查,但是(如果他們這樣做的話)最好在命中正確的檢查之前盡量減少必須完成的檢查次數。

最後一點:您沒有指定您正在使用的 DBMS,而且我介紹的某些內容可能無法在全球範圍內使用。我主要使用 MS SQL Server,這可以在那里工作。

引用自:https://dba.stackexchange.com/questions/194763