Postgres EXPLAIN 和放置索引的位置
Postgres EXPLAIN and where to put indexes
我试图从 postgres EXPLAIN
输出中理解一些意义。我想了解不同场景下索引放在哪里
一个例子是:
EXPLAIN for: SELECT "users".* FROM "users" INNER JOIN "user_sessions" ON "user_sessions"."user_id" = "users"."id" WHERE "user_sessions"."token" = 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]
的两个索引 "more" 更合适?
您可以通过删除 token
上的索引并将其替换为 (token, expires_at)
上的索引来进行改进。那么user_sessions
上的整个条件就可以作为索引条件,这样可以省去不必要的索引读取和堆检查,提高查询效率。
要查看这是否真的有很大影响,运行 EXPLAIN (ANALYZE, BUFFERS)
在两种情况下。如果过滤器删除了很多行并且接触了更多块,则查询会变慢。
user_sessions (user_id)
上的索引根本无济于事,因为永远不会搜索此条件:首先,PostgreSQL 根据 token
上的条件查找 user_session
中的所有行,然后expires_at
,然后找到 users
.
中的所有匹配行
我试图从 postgres EXPLAIN
输出中理解一些意义。我想了解不同场景下索引放在哪里
一个例子是:
EXPLAIN for: SELECT "users".* FROM "users" INNER JOIN "user_sessions" ON "user_sessions"."user_id" = "users"."id" WHERE "user_sessions"."token" = 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]
的两个索引 "more" 更合适?
您可以通过删除 token
上的索引并将其替换为 (token, expires_at)
上的索引来进行改进。那么user_sessions
上的整个条件就可以作为索引条件,这样可以省去不必要的索引读取和堆检查,提高查询效率。
要查看这是否真的有很大影响,运行 EXPLAIN (ANALYZE, BUFFERS)
在两种情况下。如果过滤器删除了很多行并且接触了更多块,则查询会变慢。
user_sessions (user_id)
上的索引根本无济于事,因为永远不会搜索此条件:首先,PostgreSQL 根据 token
上的条件查找 user_session
中的所有行,然后expires_at
,然后找到 users
.