Indeks dalam PostgreSQL - 2

Antarmuka


Pada artikel pertama , kami telah menyebutkan bahwa metode akses harus memberikan informasi tentang dirinya sendiri. Mari kita lihat struktur antarmuka metode akses.

Properti


Semua properti metode akses disimpan di tabel "pg_am" ("am" adalah singkatan dari metode akses). Kami juga bisa mendapatkan daftar metode yang tersedia dari tabel yang sama ini:

postgres=# select amname from pg_am; 
  amname -------- btree hash gist gin spgist brin (6 rows) 

Meskipun pemindaian sekuensial dapat dengan benar dirujuk ke metode akses, itu tidak ada dalam daftar ini karena alasan historis.

Dalam PostgreSQL versi 9.5 dan lebih rendah, setiap properti diwakili dengan bidang terpisah dari tabel "pg_am". Dimulai dengan versi 9.6, properti ditanya dengan fungsi-fungsi khusus dan dipisahkan menjadi beberapa lapisan:

  • Akses properti metode - "pg_indexam_has_property"
  • Properti indeks tertentu - "pg_index_has_property"
  • Properti dari masing-masing kolom indeks - "pg_index_column_has_property"

Lapisan metode akses dan lapisan indeks dipisahkan dengan pandangan ke masa depan: seperti sekarang, semua indeks berdasarkan satu metode akses akan selalu memiliki sifat yang sama.

Empat properti berikut adalah properti dari metode akses (dengan contoh "btree"):

 postgres=# select a.amname, p.name, pg_indexam_has_property(a.oid,p.name) from pg_am a, unnest(array['can_order','can_unique','can_multi_col','can_exclude']) p(name) where a.amname = 'btree' order by a.amname; 
  amname | name | pg_indexam_has_property --------+---------------+------------------------- btree | can_order | t btree | can_unique | t btree | can_multi_col | t btree | can_exclude | t (4 rows) 

  • can_order.
    Metode akses memungkinkan kami untuk menentukan urutan sortir untuk nilai saat indeks dibuat (hanya berlaku untuk "btree" sejauh ini).
  • can_unique
    Dukungan kendala unik dan kunci utama (hanya berlaku untuk "btree").
  • can_multi_col.
    Indeks dapat dibangun di beberapa kolom.
  • can_exclude
    Dukungan kendala pengecualian TIDAK TERMASUK.

Properti berikut berkaitan dengan indeks (mari kita pertimbangkan yang sudah ada misalnya):

 postgres=# select p.name, pg_index_has_property('t_a_idx'::regclass,p.name) from unnest(array[ 'clusterable','index_scan','bitmap_scan','backward_scan' ]) p(name); 
  name | pg_index_has_property ---------------+----------------------- clusterable | t index_scan | t bitmap_scan | t backward_scan | t (4 rows) 

  • berkelompok.
    Kemungkinan untuk menyusun ulang baris menurut indeks (pengelompokan dengan perintah CLUSTER dengan nama yang sama).
  • index_scan.
    Dukungan pemindaian indeks. Meskipun properti ini mungkin tampak aneh, tidak semua indeks dapat mengembalikan TUT satu per satu - beberapa hasil pengembalian sekaligus dan hanya mendukung pemindaian bitmap.
  • bitmap_scan.
    Dukungan pemindaian bitmap.
  • backward_scan.
    Hasilnya dapat dikembalikan dalam urutan terbalik dari yang ditentukan saat membangun indeks.

Akhirnya, berikut ini adalah properti kolom:

 postgres=# select p.name, pg_index_column_has_property('t_a_idx'::regclass,1,p.name) from unnest(array[ 'asc','desc','nulls_first','nulls_last','orderable','distance_orderable', 'returnable','search_array','search_nulls' ]) p(name); 
  name | pg_index_column_has_property --------------------+------------------------------ asc | t desc | f nulls_first | f nulls_last | t orderable | t distance_orderable | f returnable | t search_array | t search_nulls | t (9 rows) 

  • asc, desc, nulls_first, nulls_last, dapat dipesan.
    Properti ini terkait dengan pemesanan nilai (kami akan membahasnya ketika kami mencapai deskripsi indeks "btree").
  • distance_orderable.
    Hasilnya dapat dikembalikan dalam urutan sortir yang ditentukan oleh operasi (sejauh ini hanya berlaku untuk indeks GiST dan RUM).
  • dikembalikan
    Kemungkinan untuk menggunakan indeks tanpa mengakses tabel, yaitu dukungan scan hanya indeks.
  • search_array.
    Dukungan pencarian untuk beberapa nilai dengan ekspresi "IN -field diindeks ( list_of_constants )", yang sama dengan " indexed-field = ANY ( array_of_constants )".
  • search_nulls.
    Kemungkinan untuk mencari berdasarkan IS NULL dan IS NOT NULL.

Kami sudah membahas beberapa properti secara detail. Beberapa properti spesifik untuk metode akses tertentu. Kami akan membahas properti tersebut ketika mempertimbangkan metode khusus ini.

Kelas dan keluarga operator


Selain sifat-sifat metode akses yang diekspos oleh antarmuka yang dijelaskan, informasi diperlukan untuk mengetahui tipe data mana dan operator mana yang menerima metode akses. Untuk tujuan ini, PostgreSQL memperkenalkan konsep kelas operator dan keluarga operator .

Kelas operator berisi set minimal operator (dan mungkin, fungsi tambahan) untuk indeks untuk memanipulasi tipe data tertentu.

Kelas operator termasuk dalam beberapa keluarga operator. Selain itu, satu keluarga operator umum dapat berisi beberapa kelas operator jika mereka memiliki semantik yang sama. Misalnya, "integer_ops" keluarga termasuk "int8_ops", "int4_ops", dan "int2_ops" kelas untuk tipe "bigint", "integer", "integer", dan "smallint", memiliki ukuran berbeda tetapi artinya sama:

 postgres=# select opfname, opcname, opcintype::regtype from pg_opclass opc, pg_opfamily opf where opf.opfname = 'integer_ops' and opc.opcfamily = opf.oid and opf.opfmethod = ( select oid from pg_am where amname = 'btree' ); 
  opfname | opcname | opcintype -------------+----------+----------- integer_ops | int2_ops | smallint integer_ops | int4_ops | integer integer_ops | int8_ops | bigint (3 rows) 

Contoh lain: keluarga "datetime_ops" mencakup kelas operator untuk memanipulasi tanggal (baik dengan dan tanpa waktu):

 postgres=# select opfname, opcname, opcintype::regtype from pg_opclass opc, pg_opfamily opf where opf.opfname = 'datetime_ops' and opc.opcfamily = opf.oid and opf.opfmethod = ( select oid from pg_am where amname = 'btree' ); 
  opfname | opcname | opcintype --------------+-----------------+----------------------------- datetime_ops | date_ops | date datetime_ops | timestamptz_ops | timestamp with time zone datetime_ops | timestamp_ops | timestamp without time zone (3 rows) 

Keluarga operator juga dapat menyertakan operator tambahan untuk membandingkan nilai dari berbagai jenis. Pengelompokan ke dalam keluarga memungkinkan perencana untuk menggunakan indeks untuk predikat dengan nilai dari berbagai jenis. Sebuah keluarga juga dapat berisi fungsi bantu lainnya.

Dalam kebanyakan kasus, kita tidak perlu tahu apa-apa tentang keluarga dan kelas operator. Biasanya kami hanya membuat indeks, menggunakan kelas operator tertentu secara default.

Namun, kami dapat secara eksplisit menentukan kelas operator. Ini adalah contoh sederhana ketika spesifikasi eksplisit diperlukan: dalam database dengan susunan berbeda dari C, indeks reguler tidak mendukung operasi LIKE:

 postgres=# show lc_collate; 
  lc_collate ------------- en_US.UTF-8 (1 row) 

 postgres=# explain (costs off) select * from t where b like 'A%'; 
  QUERY PLAN ----------------------------- Seq Scan on t Filter: (b ~~ 'A%'::text) (2 rows) 

Kita dapat mengatasi batasan ini dengan membuat indeks dengan kelas operator "text_pattern_ops" (perhatikan bagaimana kondisi dalam paket telah berubah):

 postgres=# create index on t(b text_pattern_ops); postgres=# explain (costs off) select * from t where b like 'A%'; 
  QUERY PLAN ---------------------------------------------------------------- Bitmap Heap Scan on t Filter: (b ~~ 'A%'::text) -> Bitmap Index Scan on t_b_idx1 Index Cond: ((b ~>=~ 'A'::text) AND (b ~<~ 'B'::text)) (4 rows) 

Katalog sistem


Sebagai kesimpulan dari artikel ini, kami menyediakan diagram tabel yang disederhanakan dalam katalog sistem yang terkait langsung dengan kelas dan keluarga operator.



Tak perlu dikatakan bahwa semua tabel ini dijelaskan secara rinci .

Katalog sistem memungkinkan kami menemukan jawaban atas sejumlah pertanyaan tanpa melihat ke dalam dokumentasi. Misalnya, tipe data apa yang dapat dimanipulasi oleh metode akses tertentu?

 postgres=# select opcname, opcintype::regtype from pg_opclass where opcmethod = (select oid from pg_am where amname = 'btree') order by opcintype::regtype::text; 
  opcname | opcintype ---------------------+----------------------------- abstime_ops | abstime array_ops | anyarray enum_ops | anyenum ... 

Operator mana yang mengandung kelas operator (dan karenanya, akses indeks dapat digunakan untuk kondisi yang mencakup operator seperti itu)?

 postgres=# select amop.amopopr::regoperator from pg_opclass opc, pg_opfamily opf, pg_am am, pg_amop amop where opc.opcname = 'array_ops' and opf.oid = opc.opcfamily and am.oid = opf.opfmethod and amop.amopfamily = opc.opcfamily and am.amname = 'btree' and amop.amoplefttype = opc.opcintype; 
  amopopr ----------------------- <(anyarray,anyarray) <=(anyarray,anyarray) =(anyarray,anyarray) >=(anyarray,anyarray) >(anyarray,anyarray) (5 rows) 

Baca terus .

Source: https://habr.com/ru/post/id442546/


All Articles