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.