Postgresql 是否复合索引(postgres)

Postgresql 是否复合索引(postgres),postgresql,indexing,Postgresql,Indexing,我有一个列表页面正在缓慢加载,我想检查一下我是否有正确的索引 表中有500万行。每个列表都属于一个频道id。该网页仅显示一个频道的列表,已分页,因此第一个“筛选器”始终为“频道id”。在这些示例中,为了简洁起见,我将省略偏移量和限制 select * from listings where channel_id = 5; 列表也有一个状态列,默认情况下,页面打开“活动”列表 select * from listings where channel_id = 5 and status = 'ac

我有一个列表页面正在缓慢加载,我想检查一下我是否有正确的索引

表中有500万行。每个列表都属于一个频道id。该网页仅显示一个频道的列表,已分页,因此第一个“筛选器”始终为“频道id”。在这些示例中,为了简洁起见,我将省略偏移量和限制

select * from listings where channel_id = 5;
列表也有一个状态列,默认情况下,页面打开“活动”列表

select * from listings where channel_id = 5 and status = 'active';
因此,我们在(channel_id,status)上创建了一个复合索引

但我们也希望在UI中过滤并在一系列其他属性(价格、数量、类型、sku、标题、has_错误、has_警告、created_at、updated_at…等)上设置可排序的列

我从所有属性的复合索引开始,但这没有多大意义,因为您一次只能从UI中对一列进行排序

postgres的文档说:“如果其中一种查询类型远不如其他查询类型常见,那么您可能会满足于只创建两个与常见类型最匹配的索引。”

所以听起来我应该创建几个单独的索引,而不是一个巨大的复合索引。我的问题是:如果我知道我一次只处理一个频道,那么最好只创建一个索引,比如“created_at”,还是仍然在每个索引中使用channel_id为每个属性创建复合索引,例如:(channel_id,created_at)和另一个(channel_id,title)等等

在这些示例中,为了简洁起见,我将省略偏移量和限制

select * from listings where channel_id = 5;
但是您也省略了与索引相关的排序依据

但我们也希望在UI中过滤并在一系列其他属性上具有可排序的列

对于特定的查询,我们只能给出特定的建议

在这种情况下,PostgreSQL文档的引用是适用的:您可能无法为所有可能的组合创建索引,因此请选择最常见的组合,并处理它们

因此,我建议您使用所有的
where
orderby
子句获取两个最常见的查询,并将它们添加到您的问题中。这些我们可以看一看并给出建议

或者,实际上最好是,您开始学习如何为自己编制索引


最后,请注意分页查询是一个非常重要的问题,
offset
通常是一个性能威胁,最好避免:请参阅(幻灯片中的PostgreSQL基准)。

在“created_at”上创建索引。运行
explain分析查询
,编辑问题,并将输出粘贴到其中。将索引放在“created_at”上。在“(频道id,创建位置)”上创建索引。清除缓存。运行
解释分析查询
,编辑问题,并将输出粘贴到其中。这在很大程度上取决于每个索引的选择性以及复合索引是否允许查询受益于仅索引扫描。如果有疑问,请尝试查看。订单依据将是“价格”、“数量”、“sku”、“标题”、“列表类型”、“有错误”、“有警告”