Postgres EXPLAIN以及放置索引的位置

时间:2017-09-29 09:08:38

标签: postgresql indexing 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]的两个索引更“合适”?

1 个答案:

答案 0 :(得分:2)

您可以通过删除token上的索引并将其替换为(token, expires_at)上的索引来改进。然后user_sessions上的整个条件可以用作索引条件,这将节省不必要的索引读取和堆检查,并使查询更有效。

要查看这是否真的有很大影响,请在两种情况下运行EXPLAIN (ANALYZE, BUFFERS)。如果过滤器删除了大量行并且触摸了更多块,则查询将更慢。

user_sessions (user_id)上的索引根本没有帮助,因为从未搜索过这种情况:首先,PostgreSQL根据user_session和{{token上的条件查找expires_at中的所有行1}},然后它会在users中找到所有匹配的行。