Udostępnij za pośrednictwem


Optymalizowanie zapytań używających nazwanych wyrażeń

W tym artykule omówiono sposób optymalizowania wielokrotnego użycia nazwanych wyrażeń w zapytaniu.

W język zapytań Kusto nazwy można powiązać ze złożonymi wyrażeniami na kilka różnych sposobów:

Podczas odwoływanie się do tych nazwanych wyrażeń w zapytaniu są wykonywane następujące kroki:

  1. Obliczanie w nazwanym wyrażeniu jest obliczane. To obliczenie powoduje wygenerowanie wartości skalarnej lub tabelarycznej.
  2. Nazwane wyrażenie jest zastępowane wartością obliczeniową.

Jeśli ta sama nazwa powiązana jest używana wiele razy, obliczenie bazowe będzie powtarzane wiele razy. Kiedy jest to problem?

  • Gdy obliczenia zużywają wiele zasobów i są używane wiele razy.
  • Gdy obliczenie nie jest deterministyczne, ale zapytanie zakłada, że wszystkie wywołania zwracają tę samą wartość.

Ograniczanie ryzyka

Aby rozwiązać te problemy, można zmaterializować wyniki obliczeń w pamięci podczas zapytania. W zależności od sposobu definiowania nazwanego obliczenia użyjesz różnych strategii materializacji:

Funkcje tabelaryczne

Użyj następujących strategii dla funkcji tabelarycznych:

  • let, instrukcje i parametry funkcji: użyj funkcji materialize().
  • operator as: ustaw hint.materialized wartość wskazówki na true.

Na przykład następujące zapytanie używa niedeterministycznego operatora przykładu tabelarycznego:

Uwaga

Tabele nie są sortowane ogólnie, więc żadne odwołanie do tabeli w zapytaniu jest, według definicji, niedeterministyczne.

Zachowanie bez używania funkcji materializowanie

range x from 1 to 100 step 1
| sample 1
| as T
| union T

Dane wyjściowe

x
63
92

Zachowanie przy użyciu funkcji materializowanie

range x from 1 to 100 step 1
| sample 1
| as hint.materialized=true T
| union T

Dane wyjściowe

x
95
95

Funkcje skalarne

Funkcje skalarne niedeterministyczne można wymusić na obliczeniu dokładnie raz przy użyciu metody toscalar().

Na przykład następujące zapytanie używa funkcji niedeterministycznej , rand():

let x = () {rand(1000)};
let y = () {toscalar(rand(1000))};
print x, x, y, y

Dane wyjściowe

print_0 print_1 print_2 print_3
166 137 70 70