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 contentindexlapangan ( 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.