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

PostgreSQL:Mengapa kueri ini tidak menggunakan indeks saya?

Seperti yang sudah Anda sadari, masalahnya terkait dengan penggunaan operator selain yang setara. Indeks hanya dapat digunakan paling efisien untuk kolom paling kiri yang dibandingkan dengan dengan sama (ditambah satu kondisi rentang).

Dalam contoh Anda:

create index i on t (a,b,c,d);
where a=1 and b=11 and c!=5 and d<8;

Itu dapat menggunakan indeks hanya untuk a dan b efisien. Itu berarti DB mengambil semua baris yang cocok dengan a dan b kondisi dan kemudian memeriksa setiap baris terhadap kondisi yang tersisa.

Saat Anda mengubah filter di c menjadi sama, ia mengambil (berpotensi) lebih sedikit baris (hanya yang cocok dengan a dan b dan c ) dan kemudian memeriksa (lebih sedikit) baris tersebut terhadap d Saring. Menggunakan indeks lebih efisien dalam hal ini.

Secara umum, perencana kueri PostgreSQL mengevaluasi kedua opsi:(1) menggunakan indeks; (2) melakukan SeqScan. Untuk keduanya, ini menghitung nilai biaya — semakin tinggi semakin buruk kinerja yang diharapkan. Akibatnya, dibutuhkan satu dengan nilai biaya yang lebih kecil. Ini adalah bagaimana memutuskan untuk menggunakan indeks atau tidak, tidak ada ambang batas tetap.

Terakhir, ditulis "kondisi plus satu rentang" di atas. Artinya, indeks tidak hanya dapat digunakan dengan cara yang paling efisien jika Anda menggunakan tanda sama dengan, tetapi juga untuk satu kondisi rentang tunggal.

Mengingat Anda memiliki satu kondisi rentang tunggal dalam kueri Anda, saya sarankan untuk mengubah indeks seperti ini:

create index i on t (a,b,d,c);

Sekarang dapat menggunakan filter pada a dan b dan d efisien dengan indeks dan hanya perlu memfilter baris di mana c!=5 . Meskipun indeks ini dapat digunakan lebih efisien untuk kueri Anda seperti yang asli, itu tidak otomatis berarti PG akan menggunakannya. Itu tergantung pada perkiraan biaya. Tapi cobalah.

Terakhir, jika ini tidak cukup cepat dan nilai 5 yang Anda gunakan dalam ekspresi c!=5 konstan, Anda dapat mempertimbangkan indeks parsial:

 create index i on t (a,b,d)
        where c!=5;

Anda juga dapat melakukannya dengan semua kolom lain, jika nilai yang Anda bandingkan adalah konstanta.

Referensi:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Menyiapkan kunci asing dengan tipe data yang berbeda

  2. Bagaimana meningkatkan jumlah kueri teks untuk Django dengan Postgres

  3. Cara mendapatkan informasi paket kueri dari Postgres ke JDBC

  4. Postgresql - Buat Database &Tabel secara dinamis

  5. Perintah PostgreSql untuk melihat data tabel