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

Bagaimana memaksa evaluasi subquery sebelum bergabung / menekan ke server asing

Pembungkus data asing

Biasanya, gabungan atau tabel turunan apa pun dari subkueri atau CTE tidak tersedia di server asing dan harus dijalankan secara lokal. Yaitu, semua baris yang tersisa setelah WHERE simple sederhana klausa dalam contoh Anda harus diambil dan diproses secara lokal seperti yang Anda amati.

Jika semuanya gagal, Anda dapat menjalankan subquery SELECT id FROM lookup_table WHERE x = 5 dan menggabungkan hasil ke dalam string kueri.

Lebih mudahnya, Anda dapat mengotomatiskan ini dengan SQL dinamis dan EXECUTE dalam fungsi PL/pgSQL. Seperti:

CREATE OR REPLACE FUNCTION my_func(_c1 int, _l_id int)
   RETURNS TABLE(id int, c1 int, c2 int, c3 int) AS
$func$
BEGIN
   RETURN QUERY EXECUTE
     'SELECT id,c1,c2,c3 FROM big_table
      WHERE  c1 = $1
      AND    id = ANY ($2)'
   USING _c1
       , ARRAY(SELECT l.id FROM lookup_table l WHERE l.x = _l_id);
END
$func$  LANGUAGE plpgsql;

Terkait:

  • Nama tabel sebagai parameter fungsi PostgreSQL

Atau coba pencarian ini di SO.

Atau Anda dapat menggunakan meta-command \gexec di psql. Lihat:

  • Filter nama kolom dari tabel yang ada untuk pernyataan SQL DDL

Atau ini mungkin berhasil: (Umpan balik mengatakan tidak berfungsi .)

SELECT id,c1,c2,c3
FROM   big_table
WHERE  c1 = 2
AND    id = ANY (ARRAY(SELECT id FROM lookup_table WHERE x = 5));

Menguji secara lokal, saya mendapatkan paket kueri seperti ini:

Index Scan using big_table_idx on big_table (cost= ...)
  Index Cond: (id = ANY ($0))
  Filter: (c1 = 2)
  InitPlan 1 (returns $0)
    ->  Seq Scan on lookup_table  (cost= ...)
          Filter: (x = 5)

Penekanan saya yang berani.

Parameter $0 dalam rencana mengilhami harapan. Array yang dihasilkan mungkin sesuatu yang dapat diteruskan Postgres untuk digunakan dari jarak jauh. Saya tidak melihat rencana serupa dengan upaya Anda yang lain atau lebih saya mencoba sendiri. Bisakah Anda menguji dengan fdw Anda?

Pertanyaan terkait tentang postgres_fdw :

  • postgres_fdw:apakah mungkin untuk mendorong data ke server asing untuk bergabung?

Teknik umum dalam SQL

Itu cerita yang berbeda. Cukup gunakan CTE. Tapi saya tidak berharap itu membantu PLRT Asing.

WITH cte AS (SELECT id FROM lookup_table WHERE x = 5)
SELECT id,c1,c2,c3
FROM   big_table b
JOIN   cte USING (id)
WHERE  b.c1 = 2;

PostgreSQL 12 perilaku yang diubah (ditingkatkan), sehingga CTE dapat digarisbawahi seperti subkueri, dengan beberapa prasyarat. Tapi, mengutip manual:

Anda dapat mengganti keputusan itu dengan menentukan MATERIALIZED untuk memaksa perhitungan terpisah dari kueri WITH

Jadi:

WITH cte AS MATERIALIZED (SELECT id FROM lookup_table WHERE x = 5)
...

Biasanya, semua ini tidak diperlukan jika server DB Anda dikonfigurasi dengan benar dan statistik kolom diperbarui. Tetapi ada kasus sudut dengan distribusi data yang tidak merata ...




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. urutan postgresql nextval dalam skema

  2. Array PHP ke array postgres

  3. Fungsi Escape untuk ekspresi reguler atau pola LIKE

  4. Bagaimana cara membandingkan tanggal di bidang datetime di Postgresql?

  5. RPAD() Fungsi di PostgreSQL