【发布时间】:2019-05-29 20:37:18
【问题描述】:
我正在尝试索引我的查询以优化执行时间。我尝试了一些 b-tree、hash、GIN 和 GISP 索引,但 Postgres 规划器都没有使用它们。即使我定义 enable_seqscan = OFF,强制使用我的索引,执行时间仍然存在或者变得更糟。我怎样才能有效地索引这个查询?
Obs:英语不是我的主要语言,如有文字问题,请见谅
我正在使用三个表,每个表有 10k、100k 和 100k 个条目。请参阅下面的代码。而我的 PostgreSQL 版本是 9.6。
我尝试过的一些索引:
-CREATE INDEX trgm_curso_index ON curso USING gin (nome_curso gin_trgm_ops);
-CREATE INDEX trgm_natureza_index ON instituicao USING gin (natureza_administrativa gin_trgm_ops);
-CREATE INDEX fk_curso ON curso(sigla, campus);
-CREATE INDEX fk_campus ON campus(sigla);
-CREATE INDEX curso_index ON curso (nome_curso);
我的桌子:
CREATE TABLE instituicao (
sigla varchar(10),
nome_instituicao varchar(55) NOT NULL,
natureza_administrativa varchar(7) NOT NULL CHECK (natureza_administrativa IN ('Pública', 'Privada')),
nota_IGC smallint NOT NULL CHECK (nota_IGC >= 0 AND nota_IGC <= 5),
PRIMARY KEY(sigla)
);
CREATE TABLE campus(
nome_campus varchar(55) NOT NULL,
estado char(2) NOT NULL CHECK (estado IN ('AC', 'AL', 'AP', 'AM', 'BA', 'CE', 'DF', 'ES', 'GO', 'MA', 'MT', 'MS', 'MG', 'PA', 'PB', 'PR', 'PE', 'PI', 'RJ', 'RN', 'RS', 'RO', 'RR', 'SC', 'SP', 'SE', 'TO')),
cidade varchar(55) NOT NULL,
sigla varchar(10),
PRIMARY KEY(sigla, nome_campus),
FOREIGN KEY(sigla) REFERENCES instituicao(sigla) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE curso(
nome_curso varchar(55) NOT NULL,
area varchar(30) NOT NULL CHECK (area IN ('Ciências Exatas e da Terra', 'Ciências Biológicas', 'Engenharias', 'Ciências da Saúde', 'Ciências Agrárias', 'Ciências Sociais Aplicadas', 'Ciências Humanas', 'Linguística, Letras e Artes', 'Outros')),
nota_enade smallint NOT NULL CHECK (nota_enade >= 0 AND nota_enade <= 5),
grau varchar(12) NOT NULL CHECK (grau IN ('Bacharelado', 'Licenciatura', 'Mestrado', 'Doutorado', 'Tecnólogo')),
turno varchar(10) NOT NULL CHECK (turno IN ('Matutino', 'Integral', 'Noturno', 'Vespertino')),
duracao smallint NOT NULL CHECK (duracao > 0 AND duracao <= 12),
ano_criacao smallint NOT NULL CHECK (ano_criacao <= DATE_PART('YEAR', CURRENT_DATE) AND ano_criacao > 1980),
campus varchar(55) NOT NULL,
sigla varchar(10) NOT NULL,
PRIMARY KEY(sigla, campus, nome_curso),
FOREIGN KEY(sigla, campus) REFERENCES campus(sigla, nome_campus) ON DELETE CASCADE ON UPDATE CASCADE
);
我的查询:
SELECT curso.sigla, estado, campus, cidade, nome_curso, grau, turno,
duracao, nota_enade
FROM instituicao, campus, curso
WHERE instituicao.sigla = campus.sigla AND campus.nome_campus =
curso.campus AND campus.sigla = curso.sigla AND natureza_administrativa =
'Pública' AND nome_curso LIKE 'C%'
ORDER BY curso.sigla, estado, cidade;
我的 notebook 中实际执行时间是 3.6-5.7 秒,但我需要达到最大 1-2 秒。
【问题讨论】:
-
查看postgresql-performance 标签,并按照那里的建议改进您的问题。
-
我将首先重写以使用 normai
JOIN ... ON语法,这将更容易阅读并查看每个附加表中的哪些列正在连接,并将受益于索引。跨度>
标签: sql postgresql indexing postgresql-9.6 postgresql-performance