简体   繁体   English

我如何在Postgresql中索引此查询?

[英]How I can index this query in Postgresql?

I'm trying to index my query to optimize the execution time. 我正在尝试索引我的查询以优化执行时间。 I tried some b-tree, hash, GIN and GISP index but none of them have been used by the Postgres planner. 我尝试了一些b-tree,hash,GIN和GISP索引,但Postgres规划师都没有使用它们。 And even when I define enable_seqscan = OFF, to force the use of my indexes, the time of execution persists or get worse. 即使我定义enable_seqscan = OFF,强制使用我的索引,执行时间仍然存在或变得更糟。 How I can efficiently index this query? 我如何有效地索引此查询?

Obs: English is not my main language, so sorry for any textual problems Obs:英语不是我的主要语言,对于任何文字问题都很抱歉

I'm using three tables, with 10k, 100k and 100k entries each. 我正在使用三个表,每个表有10k,100k和100k条目。 See code below. 见下面的代码。 And my PostgreSQL version is 9.6. 我的PostgreSQL版本是9.6。

Some indexes that I tried: 我试过的一些索引:

-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);

My tables: 我的桌子:

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
);

My query: 我的查询:

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;

The actual execution time in my notebook is 3.6-5.7 seconds, but I need to reach a maximum of 1-2 seconds. 笔记本中的实际执行时间是3.6-5.7秒,但我需要达到最多1-2秒。

You should think about compound indexes each covering the joins and the filter here as far as possible. 你应该考虑尽可能覆盖连接和过滤器的复合索引。 Try if the following indexes help. 尝试以下索引有帮助。

CREATE INDEX curso_n_c_s
             ON curso
                (nome_curso,
                 campus,
                 sigla);
CREATE INDEX campus_n_s
             ON campus
                (nome_campus,
                 sigla);
CREATE INDEX instituicao_na_s
             ON instituicao
                (natureza_administrativa,
                 sigla);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM