我有一个包含以下列的表:
ID (VARCHAR)
CUSTOMER_ID (VARCHAR)
STATUS (VARCHAR) (4 different status possible)
other not relevant columns
我试图找到customer_id=和status=两种不同状态的所有行。
查询看起来像:
SELECT *
FROM my_table
WHERE customer_id = '12345678' AND status IN ('STATUS1', 'STATUS2');
该表包含大约100万行。我添加了关于customer_id和status的两个索引。查询仍然需要大约1秒才能运行。
解释计划是:
1. Gather
2. Seq Scan on my_table
Filter: (((status)::text = ANY ('{SUBMITTED,CANCELLED}'::text[])) AND ((customer_id)::text = '12345678'::text))
创建索引后,我运行了"analyze my_table"。我可以做些什么来提高这个非常简单的查询的性能?
您需要一个复合(多列(索引来帮助满足查询。
推测一下,似乎最具选择性的列(具有最明显值的列(是customer_id
。CCD_ 2可能只有几个不同的值。所以customer_id
应该放在索引的第一位。试试这个。
ALTER TABLE my_table ADD INDEX customer_id_status (customer_id, status);
这将创建BTREE指数。这种索引的一个有用的心理模型是一本老式的电话簿。它按顺序排序。您可以查找索引中的第一个匹配条目,然后按顺序扫描它以查找所需的项目。
您可能还想尝试运行ANALYZE my_table;
来更新查询计划器用于选择适当索引的统计信息(关于选择性(。
专业提示尽可能避免SELECT *
。请改为命名所需的列。这对性能有很大帮助。
专业提示您的问题表明您的某些列与查询优化无关。这可能不是真的;索引设计是一门怪异的艺术,SELECT *
让它变得不那么真实。