Praktik terbaik untuk kueri Bahasa Kueri Kusto

Berikut adalah beberapa praktik terbaik yang harus diikuti untuk membuat kueri Anda berjalan lebih cepat.

Singkatnya

Tindakan Penggunaan Jangan gunakan Catatan
Mengurangi jumlah data yang sedang dikueri Gunakan mekanisme seperti where operator untuk mengurangi jumlah data yang sedang diproses. Lihat di bawah ini untuk cara yang efisien untuk mengurangi jumlah data yang sedang diproses.
Hindari menggunakan referensi berkualifikasi redundan Saat mereferensikan entitas lokal, gunakan nama yang tidak memenuhi syarat. Lihat di bawah ini untuk informasi selengkapnya tentang subjek.
datetime Kolom datetime Gunakan jenis data. Jangan gunakan long jenis data. Dalam kueri, jangan gunakan fungsi konversi waktu unix, seperti unixtime_milliseconds_todatetime(). Sebagai gantinya, gunakan kebijakan pembaruan untuk mengonversi waktu unix ke datetime jenis data selama penyerapan.
Operator string Menggunakan operator has Jangan gunakan contains Saat mencari token penuh, has bekerja lebih baik, karena tidak mencari substring.
Operator peka huruf besar/kecil Gunakan == Jangan gunakan =~ Gunakan operator peka huruf besar/kecil jika memungkinkan.
Gunakan in Jangan gunakan in~
Gunakan contains_cs Jangan gunakan contains Jika Anda dapat menggunakan has/has_cs dan tidak menggunakan contains/contains_cs, itu bahkan lebih baik.
Mencari teks Lihat di kolom tertentu Jangan gunakan * * melakukan pencarian teks penuh di semua kolom.
Mengekstrak bidang dari objek dinamis di jutaan baris Materialisasikan kolom Anda pada waktu penyerapan jika sebagian besar kueri Anda mengekstrak bidang dari objek dinamis di jutaan baris. Dengan cara ini, Anda hanya akan membayar sekali untuk ekstraksi kolom.
Mencari kunci/nilai langka dalam objek dinamis Gunakan MyTable | where DynamicColumn has "Rare value" | where DynamicColumn.SomeKey == "Rare value" Jangan gunakan MyTable | where DynamicColumn.SomeKey == "Rare value" Dengan cara ini, Anda memfilter sebagian besar rekaman, dan melakukan penguraian JSON hanya dari yang lain.
let pernyataan dengan nilai yang Anda gunakan lebih dari sekali Gunakan fungsi materialize() Untuk informasi selengkapnya tentang cara menggunakan materialize(), lihat materialize(). Untuk informasi selengkapnya, lihat Mengoptimalkan kueri yang menggunakan ekspresi bernama.
Menerapkan konversi pada lebih dari 1 miliar rekaman Membentuk kembali kueri Anda untuk mengurangi jumlah data yang dimasukkan ke dalam konversi. Jangan mengonversi data dalam jumlah besar jika dapat dihindari.
Kueri baru Gunakan limit [small number] atau count di akhir. Menjalankan kueri yang tidak terikat melalui himpunan data yang tidak diketahui dapat menghasilkan GB hasil yang akan dikembalikan ke klien, yang mengakibatkan respons lambat dan kluster yang sibuk.
Perbandingan tidak peka huruf besar/kecil Gunakan Col =~ "lowercasestring" Jangan gunakan tolower(Col) == "lowercasestring"
Membandingkan data yang sudah dalam huruf kecil (atau huruf besar) Col == "lowercasestring" (atau Col == "UPPERCASESTRING") Hindari menggunakan perbandingan tidak peka huruf besar/kecil.
Pemfilteran pada kolom Filter pada kolom tabel. Jangan memfilter pada kolom terhitung.
Gunakan T | where predicate(*Expression*) Jangan gunakan T | extend _value = *Expression* | where predicate(_value)
operator summarize Gunakan kunci hint.shufflekey=<> ketika group by keys operator ringkasan memiliki kardinalitas tinggi. Kardinalitas tinggi idealnya di atas 1 juta.
operator join Pilih tabel dengan baris yang lebih sedikit untuk menjadi yang pertama (paling kiri dalam kueri).
Gunakan in alih-alih left semi join untuk memfilter dengan satu kolom.
Bergabung lintas kluster Di seluruh kluster, jalankan kueri di sisi "kanan" gabungan, tempat sebagian besar data berada.
Bergabung ketika sisi kiri kecil dan sisi kanan besar Gunakan hint.strategy=broadcast Kecil mengacu pada hingga 100MB data.
Gabungkan saat sisi kanan kecil dan sisi kiri besar Gunakan operator pencarian alih-alih join operator Jika sisi kanan pencarian lebih besar dari beberapa puluh MB, kueri akan gagal.
Bergabung ketika kedua sisi terlalu besar Gunakan kunci hint.shufflekey=<> Gunakan saat kunci bergabung memiliki kardinalitas tinggi.
Ekstrak nilai pada kolom dengan string yang berbagi format atau pola yang sama Menggunakan operator urai Jangan gunakan beberapa pernyataan extract(). Misalnya, nilai-nilai seperti "Time = <time>, ResourceId = <resourceId>, Duration = <duration>, ...."
fungsi extract() Gunakan saat string yang diurai tidak semuanya mengikuti format atau pola yang sama. Ekstrak nilai yang diperlukan dengan menggunakan REGEX.
fungsi materialize() Dorong semua operator yang mungkin yang akan mengurangi himpunan data terwujud dan tetap menyimpan semantik kueri. Misalnya, filter, atau kolom yang hanya diperlukan proyek. Untuk informasi selengkapnya, lihat Mengoptimalkan kueri yang menggunakan ekspresi bernama.
Menggunakan tampilan materialisasi Gunakan tampilan materialisasi untuk menyimpan agregasi yang umum digunakan. Utamakan menggunakan fungsi materialized_view() untuk mengkueri hanya bagian materialisasi materialized_view('MV')

Mengurangi jumlah data yang sedang diproses

Performa kueri bergantung langsung pada jumlah data yang perlu diproses. Semakin sedikit data yang diproses, semakin cepat kueri (dan semakin sedikit sumber daya yang digunakannya). Oleh karena itu, praktik terbaik yang paling penting adalah menyusun kueri sed sehingga mengurangi jumlah data yang sedang diproses.

Catatan

Dalam diskusi di bawah ini, penting untuk diingat konsep pemilihan filter. Selektivitas adalah persentase rekaman yang difilter saat memfilter berdasarkan beberapa predikat. Predikat yang sangat selektif berarti bahwa hanya beberapa catatan yang tersisa setelah menerapkan predikat, mengurangi jumlah data yang kemudian perlu diproses secara efektif.

Dalam urutan kepentingan:

  • Hanya tabel referensi yang datanya diperlukan oleh kueri. Misalnya, saat menggunakan union operator dengan referensi tabel kartubebas, lebih baik dari sudut pandang performa untuk hanya mereferensikan beberapa tabel, alih-alih menggunakan kartubebas (*) untuk mereferensikan semua tabel lalu memfilter data menggunakan predikat pada nama tabel sumber.

  • Manfaatkan cakupan data tabel jika kueri hanya relevan untuk cakupan tertentu. Fungsi table() menyediakan cara yang efisien untuk menghilangkan data dengan mencakupnya sesuai dengan kebijakan penembolokan (parameter DataScope ).

  • Terapkan where operator kueri segera mengikuti referensi tabel.

  • Saat menggunakan where operator kueri, penggunaan yudisial dari urutan predikat (dalam satu operator, atau dengan sejumlah operator berturut-turut, tidak masalah yang mana) dapat memiliki efek signifikan pada performa kueri, seperti yang dijelaskan di bawah ini.

  • Terapkan predikat seluruh pecahan terlebih dahulu. Ini berarti bahwa predikat yang menggunakan fungsi extent_id() harus diterapkan terlebih dahulu, seperti halnya predikat yang menggunakan fungsi extent_tags() dan predikat yang sangat selektif atas partisi data tabel (jika ditentukan).

  • Kemudian terapkan predikat yang bertindak berdasarkan datetime kolom tabel. Kusto menyertakan indeks yang sangat efisien pada kolom tersebut, sering menghilangkan seluruh pecahan data sepenuhnya tanpa perlu mengakses pecahan tersebut.

  • Kemudian terapkan predikat yang bertindak berdasarkan string kolom dan dynamic , terutama predikat seperti itu yang berlaku pada tingkat istilah. Predikat harus diurutkan berdasarkan selektivitas (misalnya, mencari ID pengguna ketika ada jutaan pengguna sangat selektif dan biasanya adalah pencarian istilah yang indeksnya sangat efisien.)

  • Kemudian terapkan predikat yang selektif dan didasarkan pada kolom numerik.

  • Terakhir, untuk kueri yang memindai data kolom tabel (misalnya, untuk predikat seperti 'contains "@!@!" yang tidak memiliki istilah dan tidak mendapat manfaat dari pengindeksan), urutkan predikat sehingga yang memindai kolom dengan lebih sedikit data akan menjadi yang pertama. Ini mengurangi kebutuhan untuk mendekompresi dan memindai kolom besar.

Hindari menggunakan referensi berkualifikasi redundan

Entitas seperti tabel dan tampilan materialisasi dirujuk berdasarkan nama. Misalnya, tabel T dapat dirujuk sebagai sederhana T (nama yang tidak memenuhi syarat ), atau dengan menggunakan kualifikasi database (misalnya database("DB").T ketika tabel berada dalam database yang disebut DB), atau dengan menggunakan nama yang sepenuhnya memenuhi syarat (misalnya cluster("X.Y.kusto.windows.net").database("DB").T).

Ini adalah praktik terbaik untuk menghindari penggunaan kualifikasi nama ketika berlebihan, karena alasan berikut:

  1. Nama yang tidak memenuhi syarat lebih mudah diidentifikasi (untuk pembaca manusia) sebagai milik database dalam cakupan.

  2. Mereferensikan entitas dalam cakupan database selalu setidaknya secepat, dan dalam beberapa kasus jauh lebih cepat, maka entitas yang termasuk dalam database lain (terutama ketika database tersebut berada di kluster yang berbeda.) Menghindari nama yang memenuhi syarat membantu pembaca untuk melakukan hal yang benar.

Catatan

Ini bukan berarti bahwa nama yang memenuhi syarat buruk untuk performa. Bahkan, Kusto dapat dalam banyak kasus untuk mengidentifikasi kapan nama yang sepenuhnya memenuhi syarat mereferensikan entitas milik database dalam cakupan dan "sirkuit pendek" kueri sehingga tidak dianggap sebagai kueri lintas kluster. Namun, kami menyarankan untuk tidak mengandalkan ini jika tidak perlu, karena alasan yang ditentukan di atas.