我试图从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 :(得分:2)
您可以通过删除token
上的索引并将其替换为(token, expires_at)
上的索引来改进。然后user_sessions
上的整个条件可以用作索引条件,这将节省不必要的索引读取和堆检查,并使查询更有效。
要查看这是否真的有很大影响,请在两种情况下运行EXPLAIN (ANALYZE, BUFFERS)
。如果过滤器删除了大量行并且触摸了更多块,则查询将更慢。
user_sessions (user_id)
上的索引根本没有帮助,因为从未搜索过这种情况:首先,PostgreSQL根据user_session
和{{token
上的条件查找expires_at
中的所有行1}},然后它会在users
中找到所有匹配的行。