Query fulltext terhadap database ini (menyimpan tiket RT ( Request Tracker )) tampaknya membutuhkan waktu yang sangat lama untuk dieksekusi. Tabel lampiran (berisi data teks lengkap) sekitar 15GB.
Skema database adalah sebagai berikut, ini sekitar 2 juta baris:
rt4 = # \ d + lampiran Tabel "public.attachments" Kolom | Ketik | Pengubah | Penyimpanan | Deskripsi ----------------- + ----------------------------- + - -------------------------------------------------- ------ + ---------- + ------------- id | integer | bukan null default default ('attachments_id_seq' :: regclass) | polos | transactionid | integer | bukan nol | polos | induk | integer | bukan nol default 0 | polos | messageid | karakter bervariasi (160) | | diperpanjang | subjek | karakter bervariasi (255) | | diperpanjang | nama file | karakter bervariasi (255) | | diperpanjang | contenttype | karakter bervariasi (80) | | diperpanjang | contentencoding | karakter bervariasi (80) | | diperpanjang | konten | teks | | diperpanjang | header | teks | | diperpanjang | pencipta | integer | bukan nol default 0 | polos | dibuat | timestamp tanpa zona waktu | | polos | contentindex | tsvector | | diperpanjang | Indeks: "attachments_pkey" KUNCI UTAMA, btree (id) "attachments1" btree (parent) "attachments2" btree (transactionid) "attachments3" btree (parent, transactionid) "contentindex_idx" gin (contentindex) Memiliki OID: tidak
Saya dapat melakukan query pada database sendiri dengan sangat cepat (<1s) dengan permintaan seperti:
select objectid
from attachments
join transactions on attachments.transactionid = transactions.id
where contentindex @@ to_tsquery('frobnicate');
Namun, ketika RT menjalankan kueri yang seharusnya melakukan pencarian indeks teks lengkap pada tabel yang sama, biasanya dibutuhkan ratusan detik untuk menyelesaikannya. Output analisis kueri adalah sebagai berikut:
Pertanyaan
SELECT COUNT(DISTINCT main.id)
FROM Tickets main
JOIN Transactions Transactions_1 ON ( Transactions_1.ObjectType = 'RT::Ticket' )
AND ( Transactions_1.ObjectId = main.id )
JOIN Attachments Attachments_2 ON ( Attachments_2.TransactionId = Transactions_1.id )
WHERE (main.Status != 'deleted')
AND ( ( ( Attachments_2.ContentIndex @@ plainto_tsquery('frobnicate') ) ) )
AND (main.Type = 'ticket')
AND (main.EffectiveId = main.id);
EXPLAIN ANALYZE
keluaran
RENCANA QUERY -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------- Agregat (biaya = 51210.60..51210.61 baris = 1 lebar = 4) (waktu aktual = 477778.806..477778.806 baris = 1 loop = 1) -> Nested Loop (biaya = 0,00..51210.57 baris = 15 lebar = 4) (waktu aktual = 17943.986..477775.174 baris = 4197 loop = 1) -> Nested Loop (biaya = 0,00..40643.08 baris = 6507 lebar = 8) (waktu aktual = 8.526..20610.380 baris = 1714818 loop = 1) -> Seq Memindai pada tiket utama (biaya = 0,00..9818,37 baris = 598 lebar = 8) (waktu aktual = 0,008..256,042 baris = 96990 loop = 1) Saring: (((status) :: teks 'dihapus' :: teks) DAN (id = efektifid) DAN ((tipe) :: teks = 'tiket' :: teks)) -> Pemindaian Indeks menggunakan transaksi1 pada transaksi transaksi_1 (biaya = 0,00..51,36 baris = 15 lebar = 8) (waktu aktual = 0,102..0.202 baris = 18 loop = 96990) Indeks Cond: (((objecttype) :: text = 'RT :: Ticket' :: text) AND (objectid = main.id)) -> Pemindaian Indeks menggunakan attachments2 pada attachments attachments_2 (biaya = 0,00..1.61 baris = 1 lebar = 4) (waktu aktual = 0.266..0.266 baris = 0 loop = 1714818) Indeks Cond: (transactionid = transaction_1.id) Saring: (contentindex @@ plainto_tsquery ('frobnicate' :: text)) Total runtime: 477778.883 ms
Sejauh yang saya tahu, masalahnya tampaknya bukan menggunakan indeks yang dibuat di contentindex
lapangan ( contentindex_idx
), melainkan melakukan filter pada sejumlah besar baris yang cocok di tabel lampiran. Jumlah baris dalam output yang dijelaskan juga tampak sangat tidak akurat, bahkan setelah yang terbaru ANALYZE
: baris yang diestimasi = 6507 baris aktual = 1714818.
Saya tidak begitu yakin ke mana harus pergi dengan ini.