对该数据库进行全文查询(存储RT(请求跟踪程序)票证)似乎需要很长时间才能执行。附件表(包含全文数据)约为15GB。
数据库模式如下,大约有200万行:
rt4 =#\ d +附件 表“ public.attachments” 专栏 类型 修饰符| 储存| 描述 ----------------- + ----------------------------- +- -------------------------------------------------- ------ + ---------- + ------------- id | 整数| 不是null默认nextval('attachments_id_seq':: regclass)| 普通 transactionid | 整数| 不为空| 普通 父| 整数| 不为null默认值0 | 普通 messageid | 角色变化(160)| | 扩展| 主题| 字符变化(255)| | 扩展| 文件名| 字符变化(255)| | 扩展| 内容类型| 角色变化(80)| | 扩展| contentencoding | 角色变化(80)| | 扩展| 内容| 文字| | 扩展| 标头| 文字| | 扩展| 创作者| 整数| 不为null默认值0 | 普通 创建| 没有时区的时间戳| | 普通 contentindex | tsvector | | 扩展| 索引: “ attachments_pkey”主键,btree(id) “ attachments1” btree(父级) “ attachments2” btree(transactionid) “ attachments3” btree(父级,transactionid) 杜松子酒(contentindex_idx)杜松子酒(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
输出
查询计划 -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------- 总计(费用= 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) 过滤器:((((status)::: text'deleted':: text)AND(id = validid)AND(((type):: text ='ticket':: text))) ->使用事务1上的transaction1进行索引扫描(成本= 0.00..51.36行= 15宽度= 8)(实际时间= 0.102..0.202行= 18循环= 96990) 索引条件:((((objecttype):: text ='RT :: Ticket':: text)AND(objectid = main.id)) ->使用附件_2上的附件2进行索引扫描(成本= 0.00..1.61行= 1宽度= 4)(实际时间= 0.266..0.266行= 0循环= 1714818) 索引条件:(transactionid = transaction_1.id) 过滤器:(contentindex @@ plainto_tsquery('frobnicate':: text)) 总运行时间:477778.883毫秒
据我所知,问题似乎在于它没有使用在contentindex
字段(contentindex_idx
)上创建的索引,而是对附件表中的大量匹配行进行了过滤。解释输出中的行计数似乎也非常不准确,即使最近ANALYZE
:估计的行= 6507,实际的行= 1714818。
我不太确定下一步该怎么做。