DAX連接表系列(四) ⅤAR変量(7)

優(yōu)化互斥計(jì)算

? ? ? ? 本內(nèi)容基于SQLBI官方文獻(xiàn)整理的簡體筆記 -- Power 零售 BI

? ? ? 本文介紹如何使用優(yōu)化:可能會導(dǎo)致查詢性能下降的互斥(相互排斥)計(jì)算的DAX表達(dá)式 。
? ? ? 在以前的文章中,我們討論了變量的重要性以及如何運(yùn)用其優(yōu)化IF函數(shù)模式,以減少對同一表達(dá)式或度量的多次計(jì)算。 但是,有些情況下,在同一表達(dá)式的不同定義分支中(比如由IF定義的多個條件結(jié)果)執(zhí)行的計(jì)算似乎很難被優(yōu)化。 例如,請考慮以下模式:

Amount := IF (<Condition>, [Credit],? [Debit])-- 如果符合條件,則計(jì)算[Credit],否則計(jì)算[Debit]。

? ? ? 這種涉及到度量A和B的情況,似乎沒有任何可能的優(yōu)化。 然而,通過考慮兩個度量A和B各自的性質(zhì):它們可能是基于某個相同基本度量的計(jì)算,只不過針對該度量定義了不同的篩選條件參數(shù)而產(chǎn)生不同的計(jì)算。 例如,度量A和B可以定義為:

Raw Amount :=SUM ( Transactions[Line Amount] )
Credit := CALCULATE (? [Raw Amount], Transactions[Type] = "Credit")
Debit : = CALCULATE ( [Raw Amount], Transactions[Type] = "Debit")

? ? ? 在這種情況下,DAX可能會生成一個查詢計(jì)劃,其中這兩種新度量均在內(nèi)部進(jìn)行計(jì)算,即使在報(bào)表中實(shí)際上僅顯示其中的某一個度量(基于同一度量定義的不同度量)。例如,通過應(yīng)用篩選來確定對IF條件的持續(xù)計(jì)算聲明。
? ? ? ? 當(dāng)然,在一般的簡單表達(dá)式中,DAX可能會應(yīng)用short-circuit? --直接短路式計(jì)算,從而跳過不必要的任何分支的計(jì)算。 但是,在復(fù)雜報(bào)表中,為了生成批量計(jì)算的高效查詢計(jì)劃,此優(yōu)化通常不可用。
? ? ? ? 那么,怎樣才能優(yōu)化相類似的這種表達(dá)呢?

? ? ? 我們知道,編寫DAX代碼時的一個經(jīng)驗(yàn)法則是:
? ? ? 先定義篩選器以篩選出計(jì)算列表,然后執(zhí)行CALCULATE計(jì)算,這比針對不同的條件而編寫不同的CALCULATE語句要更方便。 因此,以前的代碼可以寫成如下:

Raw Amount :=SUM ( Transactions[Line Amount] )
Amount := VAR TransactionType = IF ( <condition>,"Credit",? "Debit"? )
RETURN
CALCULATE (? [Raw Amount], Transactions[Type] = TransactionType? )

? ? ? 雖然,在這樣一個簡單的例子中,這種編碼可能不會轉(zhuǎn)化為性能優(yōu)勢,但在一些復(fù)雜表達(dá)中,該方法可能會更快。 可以通過測試兩種方法在特定用例上的性能來驗(yàn)證。
? ? ? 但是,這種技術(shù)會帶來兩個額外的挑戰(zhàn):
? ? (1)使用不同變量在多個步驟中分割計(jì)算會更困難;
? ? (2)使用條件語句創(chuàng)建適當(dāng)?shù)倪^濾器可能更復(fù)雜。

? ? ? 展示這種優(yōu)化的好處的一個常見例子是:顯示基于切片器選擇的時間智能度量的計(jì)算:比如定義一個元度量[Sales Amount],以及基于該度量添加一個或多個步驟、條件之后的新度量[Smart Sales]。

? ? ? 原始[Sales Amount]度量和智能[Smart Sales]度量分別定義如下:

? ? ? Sales Amount :=
? ? ?
SUMX ( Sales, Sales[Quantity] * Sales[Net Price] )
? ? ? Smart Sales := IF ( HASONEVALUE ( Period[Period] ),
? ? ? SWITCH ( VALUES ( Period[Period] ),
? ? ? "Last week",
? ? ? CALCULATE ([Sales Amount],?
? ? ? DATESINPERIOD ( 'Date'[Date], MAX ( 'Date'[Date] ),
? ? ? VALUES ( Period[Offset] ),DAY )? ),
? ? ? "Last 4 weeks",
? ? ? CALCULATE ( [Sales Amount],
? ? ? ? DATESINPERIOD (? 'Date'[Date],MAX ( 'Date'[Date] ),
? ? ? ? VALUES ( Period[Offset] ),? DAY )? ),
? ? ? "Last quarter",
? ? ? CALCULATE ( [Sales Amount],
? ? ? DATESINPERIOD ( 'Date'[Date],MAX ( 'Date'[Date] ),
? ? ? VALUES ( Period[Offset] ),DAY )),
? ? ? "MTD", CALCULATE ( [Sales Amount], DATESMTD ( 'Date'[Date] ) ),
? ? ? "QTD",? CALCULATE ( [Sales Amount], DATESQTD ( 'Date'[Date] ) ),
? ? ? "YTD",? CALCULATE ( [Sales Amount], DATESYTD ( 'Date'[Date] ) ), BLANK()? ))

? ? ? ? 該公式中 Swith的多個結(jié)果引用的是同一CaⅠculate條件。 Period--周期表包含每個時間段的period列的period? type—周期類型的定義。 在這一列中,“D”表示從所選時間段的最后一天開始的日期范圍,“I”表示必須根據(jù)時間段名稱(MTD, QTD,YTD)在特定時間智能函數(shù)中轉(zhuǎn)換的時間段。這里唯一可見的列是Period(其他參數(shù)列為隱式),它是上圖切片器中使用的列:

? ? ? ? 通過定義變量作為Date表的篩選器,你可以只使用單個CALCULATE來重寫[Smart Sales]--智能銷售度量。 試想,倘若能夠使用SWITCH函數(shù)來創(chuàng)建該篩器表達(dá)式,這當(dāng)然不失為一個好辦法,但遺憾的是:IF和SWITCH都返回標(biāo)量值而不是表格。 因此不可能編寫下面的語法:

VAR FilterDates = (前面[Smart Sales]度量公式中,從SWITCH開始的部分)

? ? ? ? 由于IF與SWITCH無法返回表,因此,可以使用它們定義計(jì)算所需的日期范圍,并將該時期范圍篩選傳遞給單個DATESBETWEEN函數(shù)。 一種可能的實(shí)現(xiàn)方式是以下度量:

? ? ? 簡體注:該公式是使用變量來定義篩選器書寫DAX步驟的又一個案例。其中變量FirstDaySelected需要具備一定的DAX內(nèi)部引擎知識。

? ? ? ? [Smart Sales New]度量可能有更好的性能。當(dāng)然,構(gòu)建DAX篩選器需要額外的成本,但這可能比定義不同的CALCULATE語句更有效。在本文所示的包含不同[Smart Sales]度量的小樣本數(shù)據(jù)文件中,這種差異并不明顯。然而,這種技術(shù)在更大的數(shù)據(jù)庫中會產(chǎn)生較大的影響,因?yàn)檫@種類型的數(shù)據(jù)庫不容易復(fù)制和下載。
? ? ? 像往常一樣,了解DAX中解決問題的不同方法總是一個好習(xí)慣。實(shí)際上,性能可能會因需求的具體細(xì)節(jié)和數(shù)據(jù)分發(fā)的不同而有所不同。
? ? ? ? 當(dāng)出現(xiàn)性能問題時,在沒有可用的特殊方式(如考慮索引或聚合優(yōu)化)來解決問題時。 有必要通過更改DAX代碼以獲得更好的執(zhí)行計(jì)劃。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容