Estou tentando criar um índice que dará suporte a consultas que usam meu operador personalizado. Isso está no PostgreSQL 10.4.
O operador personalizado
Eu segui as dicas nesta resposta SO para criar um operador que executa a correspondência de estilo "LIKE" em elementos em um texto ARRAY.
CREATE FUNCTION reverse_like (text, text) returns boolean language sql
as $$ select $2 like $1 $$;
CREATE OPERATOR <~~ ( function =reverse_like, leftarg = text, rightarg=text );
O operador acima me permite fazer coisas como
SELECT 'ab%' <~~ ANY('{"abc","def"}');
O esquema, índice e consulta
Eu tenho uma tabela com visitas de tráfego da web chamada sessions
que inclui uma coluna de matriz.
CREATE TABLE sessions
(
session_id varchar(24) NOT NULL,
first_seen timestamp,
domains varchar[]
);
Para consultar a coluna de domínios para ver se um determinado domínio (ou nome de domínio parcial/curinga) foi visitado, posso fazer o seguinte:
SELECT count(*)
FROM session_4070ba14_f081_41cb_9ef7_9dd385934da7
WHERE 'www.foo%' <~~ ANY(domains);
Eu quero acelerar as consultas acima com o índice GIN. Então eu criei o índice da seguinte forma:
CREATE INDEX idx_domains ON session USING GIN(domains);
A questão
Depois de executar analise na mesa e set enable_seqscan = false;
não tenho sorte em fazer o Postgres empregar esse índice. Está sempre fazendo um seqscan. Ele usa o índice acima de operadores de matriz, @>
mas não para o meu <~~
operador personalizado.
Eu acho que é porque o índice GIN não sabe como lidar com meu operador personalizado - então eu preciso criar uma classe de operador e depois criar meu índice usando isso? Ou crio um índice funcional?