ข้อความค้นหาแบบเต็มกับฐานข้อมูลนี้ (การเก็บตั๋ว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
ฉันไม่แน่ใจจริงๆว่าจะไปที่ไหนต่อจากนี้