文档首页/ 云数据库 GaussDB/ 开发指南(分布式_V2.0-8.x)/ FAQ/ 在使用了字符串处理函数后查询就不使用索引,该如何处理?
更新时间: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;

相关文档