Mengoptimalkan performa kueri GQL untuk grafik di Microsoft Fabric

Artikel ini menyediakan panduan untuk menulis kueri GQL (Bahasa Kueri Grafik) yang berkinerja terprediksi dan efisien saat bekerja dengan grafik di Microsoft Fabric. Rekomendasi didasarkan pada perilaku platform saat ini dan batasan yang didokumenkan.

Untuk batas keras pada ukuran grafik, ukuran hasil, dan batas waktu kueri, lihat Batasan saat ini. Beberapa rekomendasi dalam artikel ini juga berkaitan dengan cara Anda merancang skema grafik Anda. Untuk informasi selengkapnya, lihat Mendesain skema grafik.

Memulai pemfilteran sejak awal dalam pola

Tempatkan filter di dalam pola grafik daripada dalam pernyataan selanjutnya. Klausa tingkat pola-spesifik WHERE mengurangi jumlah hasil perantara sebelum join dan pernyataan berikutnya dijalankan, sehingga menurunkan biaya eksekusi secara keseluruhan.

Direkomendasikan: Filter selama pencocokan pola.

-- Pattern-level WHERE reduces intermediate results
MATCH (p:Person WHERE p.birthday < 19940101)-[:workAt]->(c:Company WHERE c.id > 1000)
RETURN p.firstName, p.lastName, c.name

Hindari: Memfilter terlambat dengan pernyataan FILTER yang terpisah.

-- Statement-level filter runs after all pattern matches are produced
MATCH (p:Person)-[:workAt]->(c:Company)
FILTER p.birthday < 19940101 AND c.id > 1000
RETURN p.firstName, p.lastName, c.name

Kedua kueri mengembalikan hasil yang sama, tetapi versi pertama memungkinkan mesin kueri memangkas baris sebelumnya dalam proses evaluasi.

Petunjuk / Saran

Anggaplah WHERE tingkat pola serupa dengan kondisi SQL JOIN ... ON. Ini membatasi kecocokan pada titik evaluasi alih-alih memfilter kumpulan hasil lengkap pasca-pemfilteran.

Tampilkan hanya properti yang Anda butuhkan

Kembalikan hanya properti simpul dan tepi yang dibutuhkan oleh skenario Anda. Hindari mengembalikan simpul penuh atau menggunakan RETURN * saat Anda hanya memerlukan subset properti.

Dalam grafik, tabel OneLake mendukung properti node. Memilih properti yang tidak perlu meningkatkan baca data, biaya serialisasi, dan ukuran respons. Selama pemodelan grafik, pilih kolom secara manual dari tabel sumber yang ingin Anda tambahkan sebagai properti jenis node.

Direkomendasikan: Proyeksi sempit.

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName, p.lastName, c.name

Hindari: Mengembalikan node penuh.

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN *

Nota

Hanya tambahkan properti jenis node selama pemodelan grafik saat diperlukan untuk kueri atau analisis. Lebih sedikit properti per simpul mengurangi overhead penyimpanan dan pengolahan kueri.

Batasi ukuran tataan hasil

Terapkan LIMIT atau kondisi pembatas lainnya saat melakukan kueri pada simpul atau hubungan yang mungkin memiliki kardinalitas tinggi. Kecocokan grafik yang tidak terbatas dapat menghasilkan kumpulan hasil yang sangat besar yang mendekati batas platform.

Direkomendasikan: Hasil terikat.

MATCH (p:Person)-[:knows]->(friend:Person)
RETURN p.firstName, friend.firstName
LIMIT 1000

Hindari: Kecocokan kardinalitas tinggi yang tidak terbatas.

MATCH (p:Person)-[:knows]->(friend:Person)
RETURN p.firstName, friend.firstName

Penting

Grafik memotong respons yang lebih besar dari 64 MB dan performa agregasi dapat tidak stabil ketika hasil melebihi 128 MB. Gunakan FILTER, LIMIT, dan GROUP BY untuk menyimpan hasil dalam batas-batas ini. Untuk informasi selengkapnya, lihat Batasan saat ini.

Jaga agar traversal tetap dangkal dan terarah

Hindari pola grafik yang sangat berlapis atau sangat kompleks. Gunakan traversal sederhana yang ditargetkan yang langsung menjawab pertanyaan tertentu. Setiap hop tambahan dalam pola panjang variabel dapat secara eksponensial meningkatkan jumlah jalur yang dievaluasi mesin, terutama dalam grafik yang terhubung secara padat.

Direkomendasikan: Batas ketat.

-- Use the narrowest hop range that answers your question
MATCH (p:Person)-[:knows]->{1,3}(friend:Person)
RETURN p.firstName, friend.firstName
LIMIT 1000

Hindari: Penelusuran kedalaman maksimum tanpa alasan yang jelas.

-- Exploring the full 8-hop limit on a dense graph is expensive
MATCH (p:Person)-[:knows]->{1,8}(friend:Person)
RETURN *

Penting

Grafik mendukung hingga delapan loncatan dalam pola panjang variabel. Meskipun demikian, gunakan batas terketat yang diizinkan skenario Anda. Dalam contoh ini, pola {1,3} secara signifikan lebih murah daripada {1,8} pada grafik yang sama.

Gunakan TRAIL untuk mencegah traversal redundan

Gunakan TRAIL mode jalur untuk mencegah mesin kueri mengunjungi kembali tepi yang sama. Dalam grafik padat, siklus dapat menyebabkan ledakan jalur eksponensial. TRAIL memastikan bahwa setiap tepi dikunjungi paling banyak sekali per jalur, yang meningkatkan ketepatan dan performa.

-- TRAIL prevents revisiting the same :knows edge
MATCH TRAIL (src:Person)-[:knows]->{1,4}(dst:Person)
WHERE src.firstName = 'Alice' AND dst.firstName = 'Bob'
RETURN count(*) AS numPaths

Tanpa TRAIL, kueri yang sama pada grafik siklik dapat menghasilkan tataan hasil yang jauh lebih besar (dan sering berlebihan).

Menggunakan variabel bersama untuk gabungan yang efisien

Saat kueri memerlukan data dari beberapa hubungan, gunakan variabel bersama untuk menggabungkan pola pada entitas yang sama. Tanpa variabel bersama, pola dapat menghasilkan produk kartesius - setiap kombinasi kecocokan dari kedua pola - yang mengarah ke tataan hasil yang jauh lebih besar.

Direkomendasikan: Variabel bersam p menyatukan pola.

-- Single shared variable ensures an efficient join
MATCH (p:Person)-[:workAt]->(c:Company),
      (p)-[:isLocatedIn]->(city:City)
RETURN p.firstName, c.name AS company, city.name AS city
LIMIT 1000

Menghindari: Pola independen tanpa variabel bersama.

-- Without a shared variable, this produces a cartesian product
MATCH (p1:Person)-[:workAt]->(c:Company),
      (p2:Person)-[:isLocatedIn]->(city:City)
RETURN p1.firstName, c.name, p2.firstName, city.name

Produk kartesius memasangkan setiap hasil dari satu pola dengan setiap hasil dari yang lain. Jika Person-workAt->Company cocok dengan 1.000 baris dan Person-isLocatedIn->City cocok dengan 500 baris, kueri mengembalikan 1.000 × 500 = 500.000 baris. Menambahkan variabel bersama membatasi gabungan sehingga hanya pasangan yang cocok yang dikembalikan.

Menentukan batasan kunci pada simpul

Tentukan batasan kunci simpul dalam jenis grafik Anda. Batasan utama memungkinkan sistem untuk mengoptimalkan kueri yang mencari simpul tertentu berdasarkan properti kuncinya, mirip dengan indeks kunci utama dalam database relasional.

Misalnya, jika tipe grafik Anda mendefinisikan id sebagai kunci untuk Person simpul:

CONSTRAINT person_pk
  FOR (n:Person) REQUIRE n.id IS KEY

Kemudian kueri yang memfilter id dapat menggunakan kunci tersebut untuk pencarian langsung:

-- Fast: the engine can look up person 12345 directly using the key
MATCH (p:Person WHERE p.id = 12345)-[:workAt]->(c:Company)
RETURN p.firstName, c.name

Tanpa filter pada properti kunci, mesin harus memindai setiap Person simpul:

-- Slower: scans all Person nodes before traversing
MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName, c.name

Petunjuk / Saran

Saat Anda memerlukan simpul tertentu, filter properti kuncinya dalam MATCH pola untuk memanfaatkan batasan yang Anda tentukan.

Pilih jenis data yang sesuai

Pilih jenis data yang paling spesifik untuk setiap properti selama pemodelan grafik. Memilih jenis yang tepat penting untuk efisiensi storage dan performa kueri. Misalnya, perbandingan numerik pada properti INT lebih cepat daripada perbandingan string pada STRING yang sama.

Untuk jenis data yang didukung, lihat Batasan saat ini — Jenis data dan Jenis properti yang didukung.

Jika memungkinkan, ambil entitas terkait dalam pola grafik tunggal daripada mengeluarkan kueri terpisah yang melintasi tepi yang sama secara independen. Menggabungkan traversal menghindari pencocokan pola redundan dan mencegah masalah kueri N+1, di mana satu kueri awal memicu kueri terpisah untuk setiap baris hasil.

Direkomendasikan: Pola gabungan tunggal.

MATCH (c:Customer)-[:purchased]->(o:Order)-[:contains]->(product:Product)
RETURN c.id, o.id, product.name
LIMIT 1000

Hindari: Dua kueri terpisah yang melintasi tepi yang sama Customer → Order.

-- Query 1: fetch 100 orders
MATCH (c:Customer)-[:purchased]->(o:Order)
RETURN c.id, o.id

-- Query 2: run once per order to get products (N+1 problem)
MATCH (o:Order)-[:contains]->(product:Product)
RETURN o.id, product.name

Menguji kueri terhadap volume data realistis

Kueri yang berkinerja baik pada himpunan data kecil mungkin tidak diskalakan secara linier. Uji kueri Anda dengan volume data yang mewakili beban kerja produksi yang diharapkan.

  • Lebih suka bentuk kueri konservatif yang menyertakan filter dan batasan.
  • Hindari kueri eksplorasi "mengembalikan semua data" pada grafik yang besar.
  • Memantau durasi kueri berkaitan dengan batas waktu 20 menit.