对该数据库进行全文查询(存储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。
我不太确定下一步该怎么做。