【问题标题】:Postgres EXPLAIN and where to put indexesPostgres EXPLAIN 和放置索引的位置
【发布时间】:2018-03-11 03:54:13
【问题描述】:

我试图从 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] 更合适?

【问题讨论】:

  • 注意:如果找到多个匹配的 user_sessions 行,您的查询将产生重复。 (我建议使用 EXISTS() 构造)

标签: postgresql indexing explain


【解决方案1】:

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

要查看这是否真的有很大的效果,请在这两种情况下运行EXPLAIN (ANALYZE, BUFFERS)。如果有很多行被过滤器删除并且接触的块更多,查询会变慢。

user_sessions (user_id) 上的索引根本没有帮助,因为从不搜索这个条件:首先,PostgreSQL 根据tokenexpires_at 上的条件查找user_session 中的所有行,然后找到所有匹配users 中的行。

【讨论】:

  • 很棒的反应,最后一段是正确的。现在我对它的工作原理有了更好的理解。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-15
  • 2017-10-31
  • 1970-01-01
  • 2021-05-23
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多