使用复合索引过滤的数据库

Database where filter using compound index

我有一个喜欢的对象,可以用来保持对任何其他数据库的喜欢 table,每个由 content_type_id

表示
SELECT * 
from like LEFT OUTER JOIN "accounts_user" 
  ON ("like"."user_id" = "accounts_user"."id") 
WHERE ("like"."object_id" = %s AND "like"."content_type_id" = %s AND "like"."like" = %s)`

like 是一个布尔字段。该数据库的最佳索引(索引)是什么 table?

操作是,检查用户是否喜欢某个对象,并检查哪些用户喜欢哪些对象。

我目前的指数是

CREATE INDEX like_417f1b1d ON like USING btree (content_type_id)
CREATE INDEX like_e8701ad5 ON like USING btree (user_id)
CREATE UNIQUE INDEX like_user_id_uniq ON like USING btree (user_id, content_type_id, object_id

)

查询计划是:

Query plan -> Nested Loop Left Join (cost=26563.29..168218.18 rows=1 width=1383) Query plan -> Bitmap Heap Scan on like (cost=26562.86..168209.72 rows=1 width=29) Query plan Recheck Cond: ? Query plan Filter: ? Query plan -> Bitmap Index Scan on like_417f1b1d (cost=0.00..26562.86 rows=1271257 width=0) Query plan Index Cond: ? Query plan -> Index Scan using accounts_user_pkey on accounts_user (cost=0.43..8.45 rows=1 width=1354) Query plan Index Cond: ?

你能发现任何违规行为吗?因为这花费的时间比预期的要长。 (1.5 秒)

我假设因为我拥有的索引不是确切的 WHERE 子句,这可能会导致速度变慢,但数据库引擎应该足够聪明来处理它,所以这就是我来这里的原因。

我会推荐

CREATE INDEX ON like(object_id);

这假设object_id是选择性的(table中有许多不同的object_id),而content_type_idlike不是选择性的。

如果 content_type_id 有很多不同的值,请将其添加到索引中。

如果 like 分布不均匀(例如所有值的 99% 都吃了 TRUE),将其添加到索引中可能也有帮助。

我想提一下,发布这样一个被截断的执行计划根本没有帮助。我们需要完整的东西。