【发布时间】:2016-02-19 15:22:30
【问题描述】:
我有一个 Postgres 9.4 数据库,其中包含这样的表:
| id | other_id | current | dn_ids | rank |
|----|----------|---------|---------------------------------------|------|
| 1 | 5 | F | {123,234,345,456,111,222,333,444,555} | 1 |
| 2 | 7 | F | {123,100,200,900,800,700,600,400,323} | 2 |
(更新)我已经定义了几个索引。这是CREATE TABLE 语法:
CREATE TABLE mytable (
id integer NOT NULL,
other_id integer,
rank integer,
current boolean DEFAULT false,
dn_ids integer[] DEFAULT '{}'::integer[]
);
CREATE SEQUENCE mytable_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE ONLY mytable ALTER COLUMN id SET DEFAULT nextval('mytable_id_seq'::regclass);
ALTER TABLE ONLY mytable ADD CONSTRAINT mytable_pkey PRIMARY KEY (id);
CREATE INDEX ind_dn_ids ON mytable USING gin (dn_ids);
CREATE INDEX index_mytable_on_current ON mytable USING btree (current);
CREATE INDEX index_mytable_on_other_id ON mytable USING btree (other_id);
CREATE INDEX index_mytable_on_other_id_and_current ON mytable USING btree (other_id, current);
我需要像这样优化查询:
SELECT id, dn_ids
FROM mytable
WHERE other_id = 5 AND current = F AND NOT (ARRAY[100,200] && dn_ids)
ORDER BY rank ASC
LIMIT 500 OFFSET 1000
此查询运行良好,但我确信使用智能索引会更快。表中有大约 250,000 行,我总是将 current = F 作为谓词。我与存储数组进行比较的输入数组也将有 1-9 个整数。 other_id 可能会有所不同。但一般来说,在限制之前,扫描会匹配 0-25,000 行。
这是一个例子EXPLAIN:
Limit (cost=36944.53..36945.78 rows=500 width=65)
-> Sort (cost=36942.03..37007.42 rows=26156 width=65)
Sort Key: rank
-> Seq Scan on mytable (cost=0.00..35431.42 rows=26156 width=65)
Filter: ((NOT current) AND (NOT ('{-1,35257,35314}'::integer[] && dn_ids)) AND (other_id = 193))
本网站上的其他答案和Postgres docs 建议可以添加复合索引以提高性能。我已经有一个[other_id, current]。除了WHERE 子句之外,我还在各个地方读到索引可以提高ORDER BY 的性能。
用于此查询的正确复合索引类型是什么?我根本不在乎空间。
我如何对
WHERE子句中的术语进行排序重要吗?
【问题讨论】:
-
您的谓词是否是不可变的?比如:总是
current = FALSE?每个谓词有多少行以及选择性如何?表中有多少行,结果中有多少行(最小/最大/典型)?你的数组中有多少项?表定义:最好提供一个标准形式:一个完整的CREATE TABLE脚本或者你在psql 中使用\d mytable得到的东西。查询计划? ...还有更多,请考虑tag info of [postgresql-performance]中的说明。 -
1.我只是定期选择
current = FALSE,但其他部分有所不同。 2. 表中有大约 250,000 行,我一次选择 0-25,0000 之间的任何地方,但LIMIT有几百个 3. 存储数组中最多有 9 个项目,我'正在比较我的输入数组中的 0-9 个项目 -
请添加您的实际查询。
LIMIT改变了它的性质。并考虑我的其余观点。 -
谢谢,欧文。我刚刚用
CREATE TABLE语法完成了我的编辑。
标签: postgresql indexing postgresql-9.4 postgresql-performance