이 데이터베이스에 대한 전체 텍스트 쿼리 (RT ( Request Tracker ) 티켓 저장 )를 실행하는 데 시간이 오래 걸립니다. 첨부 파일 테이블 (전체 텍스트 데이터 포함)은 약 15GB입니다.
데이터베이스 스키마는 다음과 같습니다. 약 2 백만 개의 행입니다.
rt4 = # \ d + 첨부 파일
"public.attachments"표
열 | 타입 | 수정 자 | 저장 | 기술
----------------- + ----------------------------- +- -------------------------------------------------- ------ + ---------- + -------------
아이디 | 정수 | not null 기본 nextval ( 'attachments_id_seq':: regclass) | 평원 |
transactionid | 정수 | 널이 아님 | 평원 |
부모 | 정수 | not null 기본값 0 | 평원 |
messageid | 문자 변화 (160) | | 확장 |
주제 | 문자 변화 (255) | | 확장 |
파일 이름 | 문자 변화 (255) | | 확장 |
contenttype | 문자 변화 (80) | | 확장 |
contentencoding | 문자 변화 (80) | | 확장 |
내용 | 텍스트 | | 확장 |
헤더 | 텍스트 | | 확장 |
크리에이터 | 정수 | not null 기본값 0 | 평원 |
작성 | 시간대없는 타임 스탬프 | | 평원 |
contentindex | tsvector | | 확장 |
인덱스 :
"attachments_pkey"기본 키, btree (id)
"첨부 파일 1"btree (부모)
"attachments2"btree (트랜잭션 ID)
"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)
-> 티켓 메인 순서 스캔 (비용 = 0.00..9818.37 행 = 598 너비 = 8) (실제 시간 = 0.008..256.042 행 = 96990 루프 = 1)
필터 : (((status) :: text 'deleted':: text) AND (id = effectiveid) AND ((type) :: text = 'ticket':: text))
-> 거래 transaction_1에서 거래 1을 사용한 인덱스 스캔 (비용 = 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.883ms
내가 알 수있는 한, 문제는 contentindex필드 ( contentindex_idx)에서 생성 된 색인을 사용하지 않고 첨부 파일 테이블의 많은 수의 일치하는 행에서 필터를 수행하는 것 같습니다. Explain 출력의 행 수는 최근 ANALYZE: 예상 행 = 6507 실제 행 = 1714818 이후에도 매우 부정확 한 것으로 보입니다.
나는 이것으로 다음에 어디로 갈지 확실하지 않습니다.