2017-09-29 14 views
1

나는 postgres EXPLAIN 출력에서 ​​어떤 의미를 만들려고합니다. 다양한 시나리오에 인덱스를 넣을 위치를 배우고 싶습니다.Postgres EXPLAIN 및 인덱스를 넣을 곳

한 예는 다음과 같습니다

EXPLAIN for: SELECT "users".* FROM "users" INNER JOIN "user_sessions" ON "user_sessions"."user_id" = "users"."id" WHERE "user_sessions"."token" = $1 AND (user_sessions.expires_at > '2017-09-29 08:56:26.388291') [["token", "foo"]] 

나 제공합니다 :

Nested Loop (cost=0.30..16.35 rows=1 width=192) 
    -> Index Scan using index_user_sessions_on_token on user_sessions (cost=0.15..8.17 rows=1 width=4) 
     Index Cond: ((token)::text = 'foo'::text) 
     Filter: (expires_at > '2017-09-29 08:56:26.388291'::timestamp without time zone) 
    -> Index Scan using users_pkey on users (cost=0.15..8.17 rows=1 width=192) 
     Index Cond: (id = user_sessions.user_id) 

가 단일 인덱스 [user_id, token, expires_at]user_id[token, expires_at] 두 개의 인덱스에 비해 "더"적합 할 것인가?

+0

참고 : 일치하는 user_sessions 행이 두 개 이상있는 경우 검색어가 중복됩니다. (EXISTS() 구조를 사용하는 것이 좋습니다) – joop

답변

2

token에 색인을 추가하고 (token, expires_at)의 색인으로 바꾸면 개선 될 수 있습니다. 그런 다음 인덱스 조건으로 user_sessions의 전체 조건을 사용하면 불필요한 인덱스 읽기 및 힙 검사를 줄이고 쿼리를보다 효율적으로 수행 할 수 있습니다.

실제로 많은 효과가 있는지 확인하려면 두 경우 모두 EXPLAIN (ANALYZE, BUFFERS)을 실행하십시오. 필터에 의해 많은 행이 제거되고 더 많은 블록이 접촉되면 쿼리가 더 느려집니다.

user_sessions (user_id)에 인덱스가이 조건이 검색되지 않습니다 때문에, 전혀 도움이되지 않습니다

: 첫째, PostgreSQL의이 tokenexpires_at의 조건에 따라 user_session의 모든 행을 찾을 수는, 그것은 users에 일치하는 모든 행을 찾습니다.

+0

굉장한 응답, 마지막 단락에 자리입니다. 이제 어떻게 작동하는지 더 잘 이해할 수 있습니다. 고맙습니다! – sandelius