Truy vấn Fulltext đối với cơ sở dữ liệu này (lưu trữ vé RT ( Request Tracker ) dường như mất nhiều thời gian để thực hiện. Bảng đính kèm (chứa dữ liệu toàn văn bản) khoảng 15 GB.
Lược đồ cơ sở dữ liệu như sau, có khoảng 2 triệu hàng:
rt4 = # \ d + tệp đính kèm Bảng "public.attachments" Cột | Loại | Công cụ sửa đổi | Lưu trữ | Sự miêu tả ----------------- + ----------------------------- + - -------------------------------------------------- ------ + ---------- + ------------- id | số nguyên | không null mặc định nextval ('tệp đính kèm_id_seq' :: reggroup) | đồng bằng | giao dịch | số nguyên | không null | đồng bằng | cha mẹ | số nguyên | không null mặc định 0 | đồng bằng | tin nhắn | thay đổi ký tự (160) | | mở rộng | môn học | thay đổi ký tự (255) | | mở rộng | tên tệp | thay đổi ký tự (255) | | mở rộng | nội dung | thay đổi ký tự (80) | | mở rộng | mã hóa nội dung | thay đổi ký tự (80) | | mở rộng | nội dung | văn bản | | mở rộng | tiêu đề | văn bản | | mở rộng | người sáng tạo | số nguyên | không null mặc định 0 | đồng bằng | đã tạo | dấu thời gian không có múi giờ | | đồng bằng | contentindex | tsvector | | mở rộng | Chỉ mục: "Tệp đính kèm_pkey" KHÓA CHÍNH, btree (id) "tập tin đính kèm1" btree (phụ huynh) "Tệp đính kèm2" btree (giao dịch) "Tệp đính kèm3" btree (cha mẹ, giao dịch) "contentindex_idx" gin (contentindex) Có OID: không
Tôi có thể truy vấn cơ sở dữ liệu trên chính nó rất nhanh (<1s) bằng một truy vấn như:
select objectid
from attachments
join transactions on attachments.transactionid = transactions.id
where contentindex @@ to_tsquery('frobnicate');
Tuy nhiên, khi RT chạy một truy vấn được cho là thực hiện tìm kiếm chỉ mục toàn văn bản trên cùng một bảng, thường mất hàng trăm giây để hoàn thành. Đầu ra phân tích truy vấn như sau:
Truy vấn
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
đầu ra
KẾ HOẠCH -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------- Tổng hợp (chi phí = 51210.60..51210.61 hàng = 1 width = 4) (thời gian thực tế = 477778.806..477778.806 hàng = 1 vòng = 1) -> Vòng lặp lồng nhau (chi phí = 0,00..51210,57 hàng = 15 chiều rộng = 4) (thời gian thực tế = 17943.986..477775.174 hàng = 4197 vòng = 1) -> Vòng lặp lồng nhau (chi phí = 0,00..40643,08 hàng = 6507 chiều rộng = 8) (thời gian thực tế = 8,526..20610.380 hàng = 1714818 vòng = 1) -> Seq Quét trên vé chính (chi phí = 0,00..9818.37 hàng = 598 chiều rộng = 8) (thời gian thực tế = 0,008..256.042 hàng = 96990 vòng = 1) Bộ lọc: (((trạng thái) :: văn bản 'đã xóa' :: văn bản) VÀ (id = hiệu quả) VÀ ((loại) :: văn bản = 'vé' :: văn bản)) -> Quét chỉ mục bằng cách sử dụng giao dịch1 trên giao dịch giao dịch_1 (chi phí = 0,00..51.36 hàng = 15 width = 8) (thời gian thực tế = 0.102..0.202 hàng = 18 vòng = 96990) Chỉ số Cond: (((objecttype) :: text = 'RT :: Ticket' :: text) AND (objectid = main.id)) -> Quét chỉ mục bằng cách sử dụng tệp đính kèm2 trên tệp đính kèm tệp đính kèm_2 (chi phí = 0,00..1.61 hàng = 1 width = 4) (thời gian thực tế = 0.266..0.266 hàng = 0 vòng = 1714818) Chỉ số Cond: (giao dịch = giao dịch_1.id) Bộ lọc: (contentindex @@ plainto_tsquery ('frobnicate' :: text)) Tổng thời gian chạy: 477778.883 ms
Theo như tôi có thể nói, vấn đề có vẻ là nó không sử dụng chỉ mục được tạo trên contentindex
trường ( contentindex_idx
), mà là nó đang thực hiện một bộ lọc trên một số lượng lớn các hàng khớp trong bảng đính kèm. Số lượng hàng trong đầu ra giải thích cũng có vẻ không chính xác, thậm chí sau một hàng gần đây ANALYZE
: các hàng ước tính = 6507 hàng thực tế = 1714818.
Tôi không thực sự chắc chắn nơi tiếp theo với điều này.