tengo la siguiente tabla
CREATE TABLE test(id bigint primary key, path varchar);con el índice adicional en la columna de ruta
CREATE INDEX test_path_idx ON test(path varchar_pattern_ops);Con la consulta como esta
SELECT * FROM test WHERE path LIKE 'prefix%';se utiliza el índice en la ruta. Todavía se usa con
SELECT * FROM test WHERE path LIKE 'prefix' || '%'; Index Only Scan using test_path_idx on test (cost=0.41..8.43 rows=1 width=511) Index Cond: ((path ~>=~ 'prefix'::text) AND (path ~<~ 'prefiy'::text)) Filter: ((path)::text ~~ 'prefix%'::text)Sin embargo, si el prefijo es el resultado de una subconsulta
SELECT * FROM test WHERE path LIKE (SELECT 'prefix')::varchar || '%'; Seq Scan on test (cost=0.01..359.93 rows=20 width=511) Filter: ((path)::text ~~ ((($0)::character varying)::text || '%'::text)) InitPlan 1 (returns $0) -> Result (cost=0.00..0.01 rows=1 width=32)el índice no se utiliza. Por supuesto, en realidad la subconsulta es más complicada, pero lo anterior es suficiente para que el optimizador "ignore" el índice.
Supongo que sucede porque el optimizador no puede estar seguro de que no haya comodines en el resultado de la subconsulta, por lo que toma la ruta del "peor de los casos". ¿Hay alguna manera de optimizar esto? Desafortunadamente, ejecutar la selección interna en una consulta separada e ingresar el resultado no es una opción.
PD He probado esto en 9.6.