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

Mengapa menggunakan bidang yang sama saat memfilter menyebabkan waktu eksekusi yang berbeda? (penggunaan indeks berbeda)

Sebagai solusi masalah, kami juga dapat SELECT alias untuk kolom yang digunakan di PARTITION BY ekspresi. Kemudian PG menerapkan optimasi dan menggunakan indeks.

Jawaban dari pertanyaan tersebut dapat berupa:PG tidak menerapkan pengoptimalan jika jenis komposit yang digunakan . Perhatikan saat berfungsi:

PARTITION | FILTER | IS USED?
------------------------------
ALIAS     | ORIG   | NO
ALIAS     | ALIAS  | YES
ORIG      | ALIAS  | NO
ORIG      | ORIG   | NO

Lihat dbfiddle ini

create table agreement ( ag_id int, name text, cost numeric(10,2) );
create index ag_idx on agreement (ag_id);
insert into agreement (ag_id, name, cost) values ( 1, '333', 22 ),
(1,'333', 33), (1, '333', 7), (2, '555', 18 ), (2, '555', 2), (3, '777', 4);
select * from agreement;

create function initial () 
returns table( agreement_id int, ag agreement ) language sql stable AS $$
select ag_id, t from agreement t;
$$;
select * from initial() t;

explain( analyze, costs, buffers, verbose ) with totals_by_ag as (
  select 
    *,
    sum( (t.ag).cost ) over ( partition by agreement_id ) as total
  from initial() t
)
select * from totals_by_ag t
where (t.ag).ag_id = 1; -- index is NOT USED

explain( analyze, costs, buffers, verbose ) with totals_by_ag as (
  select 
    *,
    sum( (t.ag).cost ) over ( partition by agreement_id ) as total
  from initial() t
)
select * from totals_by_ag t
where agreement_id = 1; -- index is used when alias for column is used

explain( analyze, costs, buffers, verbose ) with totals_by_ag as (
  select 
    *,
    sum( (t.ag).cost ) over ( partition by (t.ag).ag_id ) as total --renamed
  from initial() t
)
select * from totals_by_ag t
where agreement_id = 1; -- index is NOT USED because grouping by original column

explain( analyze, costs, buffers, verbose ) with totals_by_ag as (
  select 
    *,
    sum( (t.ag).cost ) over ( partition by (t.ag).ag_id ) as total --renamed
  from initial() t
)
select * from totals_by_ag t
where (t.ag).ag_id = 1; -- index is NOT USED even if at both cases original column




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana saya bisa mendapatkan daftar semua fungsi yang disimpan dalam database skema tertentu di PostgreSQL?

  2. Bagaimana cara menjatuhkan banyak (tetapi tidak semua) tabel dalam satu gerakan?

  3. Koneksi localhost Postgresql - Koneksi ditolak

  4. Cara Menyebarkan PostgreSQL untuk Ketersediaan Tinggi

  5. Tertinggi per setiap grup