PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Bergabunglah dengan dua tabel menggunakan id dan turunan dari tabel seperti pohon

Mengintegrasikan kueri

Meningkatkan logika di beberapa tempat, Anda dapat mengintegrasikan seluruh operasi dalam satu kueri. Membungkus ke dalam fungsi SQL adalah opsional:

CREATE OR REPLACE FUNCTION f_elems(_action_id integer)
  RETURNS SETOF integer AS
$func$
   WITH RECURSIVE l AS (
      SELECT a.category_id, l.local_id
      FROM   action a
      JOIN   local  l USING (local_id)
      WHERE  a.action_id = $1

      UNION ALL 
      SELECT l.category_id, c.local_id
      FROM   l
      JOIN   local c ON c.parent_id = l.local_id  -- c for "child"
      )
   SELECT e.element_id
   FROM   l
   JOIN   element e USING (category_id, local_id);
$func$  LANGUAGE sql STABLE;

Mengambil semua element_id untuk yang sama dan anak-lokal dari action_id yang diberikan .

Telepon:

SELECT * FROM f_elem(3);

element_id
-----------
6
7

db<>fiddle di sini
LAMA sqlfiddle

Ini seharusnya secara substansial lebih cepat karena beberapa alasan. Yang paling jelas adalah:

  • Ganti SQL murni untuk perulangan lambat di plpgsql.
  • Persempit set awal kueri rekursif.
  • Hapus IN yang tidak perlu dan terkenal lambat membangun.

Saya menelepon dengan SELECT * FROM ... alih-alih hanya SELECT , meskipun baris hanya memiliki satu kolom, untuk mendapatkan nama kolom OUT parameter (element_id ) Saya mendeklarasikan di header fungsi.

Lebih cepat, namun

Indeks

Indeks di action.action_id disediakan oleh kunci utama.

Tetapi Anda mungkin melewatkan indeks di local.parent_id . Saat melakukannya, jadikan itu indeks multi-kolom yang mencakup (Postgres 9.2+) dengan parent_id sebagai elemen pertama dan local_id sebagai kedua. Ini akan banyak membantu jika tabel local besar. Tidak terlalu banyak atau tidak sama sekali untuk meja kecil:

CREATE INDEX l_mult_idx ON local(parent_id, local_id);

Mengapa? Lihat:

Terakhir, indeks multi-kolom di atas tabel element harus membantu lagi:

CREATE INDEX e_mult_idx ON element (category_id, local_id, element_id);

Kolom ketiga element_id hanya berguna untuk menjadikannya indeks penutup . Jika kueri Anda mengambil lebih banyak kolom dari tabel element , Anda mungkin ingin menambahkan lebih banyak kolom ke indeks atau melepaskan element_id . Keduanya akan membuatnya lebih cepat.

Tampilan material

Jika tabel Anda menerima sedikit atau tidak ada pembaruan, tampilan terwujud yang menyediakan set semua pasangan yang telah dihitung sebelumnya (action_id, element_id) berbagi kategori yang sama akan membuat ini secepat kilat . Buat (action_id, element_id) (dalam urutan itu) kunci utama.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. psycopg2 dan keamanan injeksi SQL

  2. Npgsql dengan Pgbouncer di Kubernetes - pooling &keepalives

  3. JPA Hibernate memanggil prosedur tersimpan

  4. cap waktu postgresql ke nilai std::chrono

  5. Tidak dapat menyimpan Euro-sign ke properti LOB String dengan Hibernate/PostgreSQL