更新时间:2024-11-12 GMT+08:00
在使用了字符串处理函数后查询就不使用索引,该如何处理?
答:在索引列上使用函数处理后就不会走标准的索引,可以创建一个表达式索引,以lpad()函数为例。
--建表并插入数据。 gaussdb=# CREATE TABLE tbl_test (c1 varchar); gaussdb=# INSERT INTO tbl_test VALUES (generate_series(1,10000)); --普通索引使用lpad()函数,查询不会使用该索引。 gaussdb=# CREATE INDEX idx_test_c1 ON tbl_test(c1); gaussdb=# SET enable_fast_query_shipping TO off; --执行计划部分内容如下。 gaussdb=# EXPLAIN ANALYZE SELECT * FROM tbl_test WHERE lpad(c1,5,'0') = '00324'; id | operation | A-time | A-rows | E-rows | Peak Memory | A-width | E-width | E-costs ----+------------------------------+---------------+--------+--------+-------------+---------+---------+--------- 1 | -> Streaming (type: GATHER) | 10.594 | 1 | 1 | 79KB | | 4 | 63.12 2 | -> Seq Scan on tbl_test | [1.674,2.418] | 1 | 1 | [15KB,56KB] | | 4 | 62.99 (2 rows) Predicate Information (identified by plan id) ------------------------------------------------------------------ 2 --Seq Scan on tbl_test Filter: (lpad((c1)::text, 5, '0'::text) = '00324'::text) Rows Removed by Filter: 9999 (3 rows) --修改为表达式索引后,该查询会使用索引。 gaussdb=# DROP INDEX idx_test_c1; gaussdb=# CREATE INDEX idx_test_c1 ON tbl_test(lpad(c1,5,'0')); gaussdb=# EXPLAIN ANALYZE SELECT * FROM tbl_test WHERE lpad(c1,5,'0') = '00324'; id | operation | A-time | A-rows | E-rows | Peak Memory | A-width | E-width | E-costs ----+-------------------------------------------------+---------------+--------+--------+-------------+---------+---------+--------- 1 | -> Streaming (type: GATHER) | 4.632 | 1 | 1 | 80KB | | 4 | 8.39 2 | -> Index Scan using idx_test_c1 on tbl_test | [0.168,0.194] | 1 | 1 | [70KB,70KB] | | 4 | 8.27 (2 rows) Predicate Information (identified by plan id) ---------------------------------------------------------------------- 2 --Index Scan using idx_test_c1 on tbl_test Index Cond: (lpad((c1)::text, 5, '0'::text) = '00324'::text) (2 rows) --删除。 gaussdb=# DROP INDEX idx_test_c1; gaussdb=# DROP TABLE tbl_test;
父主题: FAQ