ข้อความค้นหาแบบเต็มกับฐานข้อมูลนี้ (การเก็บตั๋วRT ( Request Tracker )) ดูเหมือนจะใช้เวลานานมากในการดำเนินการ ตารางสิ่งที่แนบ (มีข้อมูลแบบเต็ม) ประมาณ 15GB
สคีมาฐานข้อมูลมีดังนี้ประมาณ 2 ล้านแถว:
rt4 = # \ d + ไฟล์แนบ
ตาราง "public.attachments"
คอลัมน์ | ประเภท | ตัวดัดแปลง | จัดเก็บข้อมูล | ลักษณะ
----------------- + ----------------------------- + - -------------------------------------------------- ------ ---------- + + -------------
id | จำนวนเต็ม ไม่ใช่ null ค่าเริ่มต้น nextval ('Attachments_id_seq' :: regclass) | ธรรมดา
ธุรกรรม | จำนวนเต็ม ไม่เป็นโมฆะ ธรรมดา
parent | จำนวนเต็ม ไม่ใช่ค่าเริ่มต้นเป็นศูนย์ 0 | ธรรมดา
messageid | อักขระแตกต่างกัน (160) | | ขยาย
หัวเรื่อง | อักขระแตกต่างกัน (255) | | ขยาย
ชื่อไฟล์ อักขระแตกต่างกัน (255) | | ขยาย
contenttype | อักขระแตกต่างกัน (80) | | ขยาย
การเข้ารหัสเนื้อหา | อักขระแตกต่างกัน (80) | | ขยาย
เนื้อหา | ข้อความ | | ขยาย
ส่วนหัว ข้อความ | | ขยาย
ผู้สร้าง | จำนวนเต็ม ไม่ใช่ค่าเริ่มต้นเป็นศูนย์ 0 | ธรรมดา
สร้าง | การประทับเวลาที่ไม่มีโซนเวลา | | ธรรมดา
contentindex | tsvector | | ขยาย
ดัชนี:
"Attachments_pkey" คีย์หลัก, btree (id)
"Attachments1" btree (parent)
"เอกสารแนบ 2" btree (transactionid)
"Attachments3" btree (parent, transactionid)
"contentindex_idx" gin (contentindex)
มี OID: ไม่
ฉันสามารถสืบค้นฐานข้อมูลด้วยตัวเองได้อย่างรวดเร็ว (<1s) ด้วยแบบสอบถามเช่น:
select objectid
from attachments
join transactions on attachments.transactionid = transactions.id
where contentindex @@ to_tsquery('frobnicate');
อย่างไรก็ตามเมื่อ RT รันเคียวรีที่ควรทำการค้นหาดัชนีแบบเต็มบนตารางเดียวกันโดยทั่วไปจะใช้เวลาหลายร้อยวินาทีในการทำให้เสร็จสมบูรณ์ แบบสอบถามวิเคราะห์ผลลัพธ์เป็นดังนี้:
สอบถาม
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 เอาท์พุต
แผน QUERY
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------
ผลรวม (ราคา = 51210.60..51210.61 แถว = 1 ความกว้าง = 4) (เวลาจริง = 477778.806..477778.806 แถว = 1 ลูป = 1)
-> วนซ้ำ (ต้นทุน = 0.00..51210.57 แถว = 15 ความกว้าง = 4) (เวลาจริง = 17943.986..477775.174 แถว = 4197 ลูป = 1)
-> วนซ้ำ (ต้นทุน = 0.00..40643.08 แถว = 6507 ความกว้าง = 8) (เวลาจริง = 8.526..20610.380 แถว = 1714818 ลูป = 1)
-> Seq สแกนบนตั๋วหลัก (ราคา = 0.00..9818.37 แถว = 598 กว้าง = 8) (เวลาจริง = 0.008 ..256.042 แถว = 96990 ลูป = 1)
ตัวกรอง: ((((สถานะ) :: ข้อความ 'ลบ' :: ข้อความ) และ (id = effectiveid) และ ((ประเภท) :: text = 'ตั๋ว' :: ข้อความ))
-> การสแกนดัชนีโดยใช้ทรานแซคชัน 1 ในทรานแซคชัน transaction_1 (ต้นทุน = 0.00..51.36 แถว = 15 ความกว้าง = 8) (เวลาจริง = 0.102..0.202 แถว = 18 ลูป = 96990)
ดัชนี Cond: ((((objecttype)) :: text = 'RT :: Ticket' :: text) AND (objectid = main.id))
-> ดัชนีการสแกนโดยใช้ไฟล์แนบ 2 ในไฟล์แนบ Attachments_2 (ราคา = 0.00..1.61 แถว = 1 ความกว้าง = 4) (เวลาจริง = 0.266..0.266 แถว = 0 ลูป = 1714818)
ดัชนี Cond: (transactionid = transaction_1.id)
ตัวกรอง: (contentindex @@ plainto_tsquery ('frobnicate' :: ข้อความ))
รันไทม์ทั้งหมด: 477778.883 ms
เท่าที่ฉันสามารถบอกได้ปัญหาดูเหมือนว่ามันไม่ได้ใช้ดัชนีที่สร้างขึ้นในcontentindexฟิลด์ ( contentindex_idx) แต่มันกำลังทำตัวกรองในจำนวนแถวที่ตรงกันจำนวนมากในตารางสิ่งที่แนบมา จำนวนแถวในเอาต์พุตอธิบายยังดูเหมือนว่าไม่ถูกต้องอย่างดุเดือดแม้กระทั่งเมื่อเร็ว ๆ นี้ANALYZE: แถวโดยประมาณ = 6507 แถวจริง = 1714818
ฉันไม่แน่ใจจริงๆว่าจะไปที่ไหนต่อจากนี้