Praktik terbaik kueri grafik
Dokumen ini menjelaskan praktik terbaik untuk mengoptimalkan kueri BigQuery Graph Anda.
Memulai path traversal dari node kardinalitas rendah
Untuk menjaga agar kumpulan hasil perantara tetap kecil dan mempercepat eksekusi kueri, tulis kueri grafik sehingga traversal jalur dimulai dari node kardinalitas yang lebih rendah, terlepas dari arah traversal jalur. Pernyataan MATCH berikut menggunakan filter properti untuk mengurangi jumlah kemungkinan node awal, bukan menghitung semua kecocokan, lalu memfilter:
MATCH (p:Person {id: 10})-[own:Owns]->(a:Account)
MATCH (a:Account WHERE balance > 10)<-[own:Owns]-(p:Person)
Hal ini sangat penting untuk kueri jalur terkuantifikasi:
MATCH (p:Person {id: 10})-[own:Owns]->{1,3}(a:Account)
Menggunakan sintaksis ANY atau ANY SHORTEST untuk pemeriksaan konektivitas
Kueri jalur terkuantifikasi dapat menampilkan jalur duplikat antara node sumber dan node tujuan. Jika tujuan Anda adalah memeriksa konektivitas dan Anda tidak
memerlukan semua jalur yang memungkinkan, gunakan ANY atau ANY SHORTEST untuk mengurangi komputasi yang berlebihan
dan meningkatkan efisiensi pencarian jalur. Misalnya, pernyataan MATCH berikut menggunakan ANY SHORTEST untuk hanya menyimpan satu jalur di antara setiap pasangan node:
MATCH ANY SHORTEST (a1:Account)-[t:Transfers]->{1,3}(a2:Account)
Menggunakan traversal jalur terarah
Skema BigQuery Graph bersifat terarah, yang berarti setiap edge memiliki node sumber dan node tujuan. Meskipun sintaksis kueri grafik
memungkinkan traversal jalur ke segala arah (misalnya, -[edge]-), sebaiknya gunakan traversal jalur terarah (misalnya, -[edge]-> atau
<-[edge]-) untuk performa yang lebih baik. Traversal jalur ke segala arah dapat menyebabkan penurunan performa.
Pernyataan MATCH berikut menggunakan path traversal ke segala arah:
-- Avoid.
MATCH (a1:Account {id: 7})-[t:Transfers]-(a2:Account)
Sebagai gantinya, gabungkan dua traversal terarah dengan UNION ALL:
MATCH (a1:Account {id: 7})-[t:Transfers]->(a2:Account)
...
UNION ALL
...
MATCH (a1:Account {id: 7})<-[t:Transfers]-(a2:Account)
Menentukan label secara eksplisit
Jika label node atau edge dihilangkan dalam kueri, BigQuery Graph akan menghitung semua label node dan edge yang memenuhi syarat. Penghitungan ini dapat menyebabkan lebih banyak label dipindai daripada yang diperlukan. Untuk menghindarinya, tentukan label untuk semua node dan edge dalam kueri Anda jika memungkinkan.
Misalnya, kueri berikut menentukan label Account dan Transfers:
GRAPH graph_db.FinGraph
MATCH (a1:Account)-[t:Transfers]->(a2:Account)
RETURN COUNT(*) AS num_transfers;
Hindari menghilangkan label, karena tindakan ini dapat memindai hubungan lain yang tidak diperlukan antar-node. Dalam kueri berikut, a1 dapat mewakili akun atau a
orang, dan t dapat mewakili transfer atau kepemilikan akun.
GRAPH graph_db.FinGraph
MATCH (a1)-[t]->(a2)
RETURN COUNT(*) AS num_transfers;
Lebih memilih satu pernyataan MATCH
BigQuery Graph memungkinkan Anda menyertakan beberapa pernyataan MATCH dalam satu kueri grafik. Pernyataan ini terhubung oleh variabel yang dideklarasikan beberapa kali yang mewakili node atau edge yang sama. Namun, penggunaan beberapa pernyataan MATCH dapat mengurangi manfaat kardinalitas di seluruh pernyataan. Jika memungkinkan, gunakan satu pernyataan MATCH untuk performa yang lebih baik.
Misalnya, kueri berikut setara, tetapi kueri pertama berperforma lebih baik karena menggunakan satu pernyataan MATCH:
-- Preferred syntax.
GRAPH graph_db.FinGraph
MATCH
(p:Person {id: 1})-[o:Owns]->
(a:Account)-[t:Transfers]->(a2:Account)
RETURN o.account_id, t.amount;
-- Avoid this syntax.
GRAPH graph_db.FinGraph
MATCH (p:Person {id: 1})-[o:Owns]->(a:Account)
MATCH (a:Account)-[t:Transfers]->(a2:Account)
RETURN o.account_id, t.amount;
Membatasi edge yang dilalui dari node kardinalitas tinggi
Saat Anda membuat kueri grafik, beberapa node dapat memiliki jumlah edge masuk atau keluar yang jauh lebih besar dibandingkan dengan node lainnya. Node kardinalitas tinggi ini terkadang disebut node super atau node hub. Node super dapat menyebabkan masalah performa karena traversal melalui node tersebut mungkin melibatkan pemrosesan data dalam jumlah besar, yang menyebabkan kecondongan data dan waktu eksekusi yang lama.
Untuk mengoptimalkan kueri grafik dengan node super, gunakan fungsi
ROW_NUMBER()
dalam klausa FILTER atau klausa WHERE di MATCH untuk membatasi
jumlah edge yang dilalui kueri dari atau ke node. Teknik ini sangat berguna jika Anda tidak memerlukan penghitungan lengkap semua koneksi dari atau ke node super.
Misalnya, jika beberapa akun di FinGraph memiliki sejumlah besar transaksi, Anda dapat menggunakan ROW_NUMBER() untuk membatasi jumlah edge Transfers yang akan dipertimbangkan untuk setiap Account dan menghindari kueri yang tidak efisien:
GRAPH graph_db.FinGraph
MATCH (a1:Account)-[e1:Transfers WHERE e1 IN {
GRAPH graph_db.FinGraph
-- Sample 5 edges per source node
MATCH -[selected_e:Transfers]->
FILTER ROW_NUMBER() OVER (
PARTITION BY SOURCE_NODE_ID(selected_e)) < 5
RETURN selected_e
}]->{1,3}(a2:Account)
RETURN COUNT(*) AS cnt;
Mengambil sampel node atau edge perantara dalam kueri multi-hop
Anda juga dapat meningkatkan efisiensi kueri dengan menggunakan ROW_NUMBER() untuk mengambil sampel node perantara dalam kueri multi-hop. Teknik ini meningkatkan efisiensi dengan membatasi jumlah jalur yang dipertimbangkan kueri untuk setiap node perantara. Untuk melakukannya, pisahkan kueri multi-hop menjadi beberapa pernyataan MATCH yang dipisahkan oleh NEXT, dan terapkan ROW_NUMBER() di titik tengah tempat Anda perlu mengambil sampel:
GRAPH graph_db.FinGraph
MATCH (a1:Account)-[e1:Transfers]->(a2:Account)
-- Sample 5 destination nodes per a1 source node
FILTER ROW_NUMBER() OVER (PARTITION BY ELEMENT_ID(a1)) < 5
RETURN a1, a2
NEXT
MATCH (a2)-[e2:Transfers]->(a3:Account)
RETURN a1.id AS src_id, a2.id AS mid_id, a3.id AS dst_id;
Langkah berikutnya
- Untuk mempelajari lebih lanjut cara menulis kueri grafik, lihat ringkasan kueri.
- Pelajari lebih lanjut cara mendesain skema grafik .