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.

中的所有匹配行