I가 큰 데이터베이스에 느린하는 다음과 같은 선택 :- PostgreSQL의
SELECT eventid
FROM track_event
WHERE inboundid IN (SELECT messageid FROM temp_message);
temp_message 테이블은 작은 (100 행) 및 하나의 열 (주의 messageid VARCHAR)입니다 열의 btree 인덱스
track_event 테이블에는 19 개의 열과 거의 1300 만 개의 행이 있습니다. 이 쿼리에 사용 된 열 (eventid bigint 및 inboundid varchar)에는 모두 btree 인덱스가 있습니다.
나는이 큰 데이터베이스에서 계획을 설명 복사/붙여 넣기,하지만 여기에 같은 스키마 (track_event 만 348 행) 작은 데이터베이스에서 계획의 수 :
explain analyse SELECT eventid FROM track_event WHERE inboundid IN (SELECT messageid FROM temp_message);
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------
Nested Loop Semi Join (cost=0.00..60.78 rows=348 width=8) (actual time=0.033..3.186 rows=348 loops=1)
-> Seq Scan on track_event (cost=0.00..8.48 rows=348 width=25) (actual time=0.012..0.860 rows=348 loops=1)
-> Index Scan using temp_message_idx on temp_message (cost=0.00..0.48 rows=7 width=32) (actual time=0.005..0.005 rows=1 loops=348)
Index Cond: ((temp_message.messageid)::text = (track_event.inboundid)::text)
Total runtime: 3.349 ms
(5 rows)
큰 데이터베이스에 이 쿼리에는 약 450 초가 걸립니다. 누구나 분명한 속도 향상을 볼 수 있습니까? 설명 계획에 track_event의 Seq Scan이 있음을 알았습니다. 잃어 버리고 싶지만 대신 사용할 수있는 인덱스를 찾을 수는 없습니다.
는
포스트 그레스 9.0
track_event 테이블 내가 큰 변화를 만들 수없는 매우 큰 복잡한 스키마의 일부를 편집합니다. 방금 추가 한 새 색인을 포함한 정보는 다음과 같습니다.
Table "public.track_event"
Column | Type | Modifiers
--------------------+--------------------------+-----------
eventid | bigint | not null
messageid | character varying | not null
inboundid | character varying | not null
newid | character varying |
parenteventid | bigint |
pmmuser | bigint |
eventdate | timestamp with time zone | not null
routeid | integer |
eventtypeid | integer | not null
adminid | integer |
hostid | integer |
reason | character varying |
expiry | integer |
encryptionendpoint | character varying |
encryptionerror | character varying |
encryptiontype | character varying |
tlsused | integer |
tlsrequested | integer |
encryptionportal | integer |
Indexes:
"track_event_pk" PRIMARY KEY, btree (eventid)
"foo" btree (inboundid, eventid)
"px_event_inboundid" btree (inboundid)
"track_event_idx" btree (messageid, eventtypeid)
Foreign-key constraints:
"track_event_parent_fk" FOREIGN KEY (parenteventid) REFERENCES track_event(eventid)
"track_event_pmi_route_fk" FOREIGN KEY (routeid) REFERENCES pmi_route(routeid)
"track_event_pmim_smtpaddress_fk" FOREIGN KEY (pmmuser) REFERENCES pmim_smtpaddress(smtpaddressid)
"track_event_track_adminuser_fk" FOREIGN KEY (adminid) REFERENCES track_adminuser(adminid)
"track_event_track_encryptionportal_fk" FOREIGN KEY (encryptionportal) REFERENCES track_encryptionportal(id)
"track_event_track_eventtype_fk" FOREIGN KEY (eventtypeid) REFERENCES track_eventtype(eventtypeid)
"track_event_track_host_fk" FOREIGN KEY (hostid) REFERENCES track_host(hostid)
"track_event_track_message_fk" FOREIGN KEY (inboundid) REFERENCES track_message(messageid)
Referenced by:
TABLE "track_event" CONSTRAINT "track_event_parent_fk" FOREIGN KEY (parenteventid) REFERENCES track_event(eventid)
TABLE "track_eventaddress" CONSTRAINT "track_eventaddress_track_event_fk" FOREIGN KEY (eventid) REFERENCES track_event(eventid)
TABLE "track_eventattachment" CONSTRAINT "track_eventattachment_track_event_fk" FOREIGN KEY (eventid) REFERENCES track_event(eventid)
TABLE "track_eventrule" CONSTRAINT "track_eventrule_track_event_fk" FOREIGN KEY (eventid) REFERENCES track_event(eventid)
TABLE "track_eventthreatdescription" CONSTRAINT "track_eventthreatdescription_track_event_fk" FOREIGN KEY (eventid) REFERENCES track_event(eventid)
TABLE "track_eventthreattype" CONSTRAINT "track_eventthreattype_track_event_fk" FOREIGN KEY (eventid) REFERENCES track_event(eventid)
TABLE "track_quarantineevent" CONSTRAINT "track_quarantineevent_track_event_fk" FOREIGN KEY (eventid) REFERENCES track_event(eventid)
1) mesaage_id가 varchar 유형이되는 이유는 무엇입니까? 2) 대용 기본 키를 추가하고 FK로 사용하고 텍스트 열에 고유 제한 조건을 추가 할 수 있습니까? 3) 'IN (...)'에 'EXISTS (...)'를 선호 할 수 있습니까? (계획에 이미 색인 스캔이 표시되어 있음에도 불구하고) 0) 테이블 정의를 질문에 추가하십시오. 0a)와 튜너 블 (random_page_cost, work_mem,?) – joop
BTW : 인덱스 조건에서의 캐스팅'((temp_message.messageid) :: text = (track_event.inboundid) :: text) '은 ** 매우 용의주 함 ** 나는 그것을 여기에서 재현 할 수 없다. (pg9.3 베타 : varchar 키에 대해서만 hashjoins를 얻는다.) Postgres 버전? ** 테이블 정의 **? – joop
joop이 Postgres 버전을 추가한다고 말했습니다. 계획과 버전이 없으면 답을 얻을 수 없습니다. – Kuberchaun