【问题标题】:PostgreSQL - Right Index choice for a status field (varchar)PostgreSQL - 状态字段的正确索引选择(varchar)
【发布时间】:2017-01-05 19:19:12
【问题描述】:

我有一个包含大量条目的表和一个长度为 8 的 varchar 字段,表示不同的状态。只有大约 5 种不同的状态,比如说“STATUS1”、“STATUS2”……而且大多数时候它是 NULL。

当我索引该字段时,它并没有做太多,因为有很多相等的值,然后 postgres 不使用索引。

我的问题是:有没有办法索引这样的字段并使其更快?大多数时候我查询status IS NULL,我想我不能让它更快。但是如果我检查 status = 'STATUS1' 会怎样?

【问题讨论】:

  • 如果你关心性能,我认为你应该考虑在这里使用整数而不是 varchars。如果状态名称很重要,您始终可以创建一个附属关系,其中包含从整数到状态名称的关联。
  • 这完全取决于where status is null 将从结果中删除多少行。如果该条件只返回几行,那么 Postgres 在状态列上使用索引。如果这是所有行中的大多数,则索引将无济于事(但值得尝试创建部分索引)
  • 我也有这个想法,但我宁愿保留 Varchar 字段。性能在这一点上并不重要,我只是想知道是否有一种我完全想念的常见方式。

标签: sql postgresql


【解决方案1】:

在某些情况下,您可以使用partial indexes。假设您有很多类似的查询

SELECT *
  FROM the_table
 WHERE color in ('green', 'blue') AND status = 'STATUS1' ;

如果你创建一个partial index,这个查询很可能会运行得更快(很多):

CREATE TABLE the_table
(
   color text, 
   status character varying(8)
    /* and anything you need */
) ; 

CREATE INDEX
  ON public.the_table (color)
  WHERE status = 'STATUS1' ;

如果使用 PostgreSQL(或任何其他允许它的数据库),我可能也会创建一个 enumerated type,而不是 varchar。您有两个优点:只允许枚举值(因此“自动检查”),存储信息(和索引)所需的空间小于 varchar(8):

CREATE TYPE status_type AS ENUM
   ('STATUS1',
    'STATUS2',
    'STATUS3');

然后用它创建表:

CREATE TABLE the_table
(
   color text, 
   status status_type
    /* and anything you need */
) ; 

如果您需要(以编程方式)了解枚举的允许值(例如,创建菜单),check here

如果数据库不允许枚举,我会规范化为 (anonymous_id_PK, status_value) 对的小型 [ish] 表。

【讨论】:

  • 我想这是最好的解决方案。我也会考虑枚举。谢谢!
猜你喜欢
  • 1970-01-01
  • 2015-03-01
  • 2021-01-12
  • 2021-02-25
  • 2021-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
相关资源
最近更新 更多