PostgreSQL 데이터베이스에서 LIKE 문장의 효율성을 보장하는 방법 (권장)

7247 단어 PostgreSQLLIKE문장
어떤 데이터베이스에서든 LIKE 문장을 사용하는 것은 흔히 골치 아픈 일이다. 많은 사용자들이 LIKE 문장의 효율이 매우 낮다는 것을 발견했기 때문이다. 실행 계획을 보고 색인을 하지 않은 것을 발견했기 때문이다. 그러면 Postgresql 데이터에서 LIKE 문장의 집행 효율은 어떨까?우리는 또 어떻게 LIKE 문장의 집행 효율을 높여야 합니까?

실험 환경


데이터베이스 환경: PostgreSQL 12.3 X86_64  
가상 환경을 만들려면 다음과 같이 하십시오.

postgres=# create database testdb01 owner highgo;
CREATE DATABASE
postgres=# \c testdb01 highgo
 
 
testdb01=# create table testliketb01 (userid int primary key,username varchar(20),password varchar(60),description text);
CREATE TABLE
왜 테스트 효과가 더욱 직관적일 수 있는지, 우리는 무작위 데이터로 이 표를 채웁니다

testdb01=# insert into testliketb01 select generate_series(1,500000),split_part(' , , , , ',',',(random()*(5-1)+1)::int),md5((random()*(5-1)+1)::varchar),split_part('highgo,highgo02,highgo03',',',(random()*(3-1)+1)::int);
이로써 가상 데이터가 생성됩니다.

testdb01=# select * from testliketb01 limit 10;
userid | username |             password             | description
--------+----------+----------------------------------+-------------
      1 |       | 4f2bca371b42abd1403d5c20c4542dff | highgo
      2 |       | 2a978c605188770c5ed162889fff189e | highgo02
      3 |       | f5d129ab728b72ac6f663fe544bc7c16 | highgo
      4 |       | 53134fa1022c58e65168b6aa1fbe5e39 | highgo02
      5 |       | 2cf9abb2a8b676a626fa2c317d401ed8 | highgo02
      6 |       | 2247a0cfda1f2819554d6e8e454622eb | highgo02
      7 |       | 59dfdc680c17533dfba1c72c9ce0bf76 | highgo02
      8 |       | 87db4258236a3826259dcc3e7cb5fc63 | highgo02
      9 |       | baaf7a2f7027df9aaeb665121432b6e2 | highgo02
     10 |       | 2f8fb36b3227c795b111b9bd5b031a76 | highgo02
(10 rows)
 :
testdb01=# \l+ testdb01
                                                List of databases
   Name   | Owner  | Encoding |   Collate   |    Ctype    | Access privileges | Size  | Tablespace | Description
----------+--------+----------+-------------+-------------+-------------------+-------+------------+-------------
testdb01 | highgo | UTF8     | en_US.UTF-8 | en_US.UTF-8 |                   | 59 MB | pg_default |
(1 row)
단순 LIKE 구문 조회:

testdb01=# explain analyze select * from testliketb01 where username like ' %';
                                                      QUERY PLAN                                                       
-----------------------------------------------------------------------------------------------------------------------
Seq Scan on testliketb01  (cost=0.00..11405.00 rows=125350 width=52) (actual time=0.014..177.571 rows=124952 loops=1)
   Filter: ((username)::text ~~ ' %'::text)
   Rows Removed by Filter: 375048
Planning Time: 0.121 ms
Execution Time: 190.554 ms
(5 rows)
결론: LIKE 조회는 인덱스가 없습니다. 일반 인덱스 만들기:testdb01=#create index idx_testliketb01_username on testliketb01(username); CREATE INDEX 세 번 실행: analyze testliketb01;LIKE 문장을 다시 실행하면operator class를 포함하는 인덱스를 만들지 않았습니다:testdb01=#create index idx_testliketb01_username on testliketb01(username varchar_pattern_ops); CREATE INDEX 세 번 실행: analyze testliketb01;   

testdb01=# explain analyze select * from testliketb01 where username like ' %';
                                                                   QUERY PLAN                                                                    
-------------------------------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on testliketb01  (cost=2665.26..9387.14 rows=125350 width=52) (actual time=31.383..94.745 rows=124952 loops=1)
   Filter: ((username)::text ~~ ' %'::text)
   Heap Blocks: exact=5155
   ->  Bitmap Index Scan on idx_testliketb01_username  (cost=0.00..2633.92 rows=125350 width=0) (actual time=29.730..29.730 rows=124952 loops=1)
         Index Cond: (((username)::text ~>=~ ' '::text) AND ((username)::text ~<~ 'U'::text))
Planning Time: 0.111 ms
Execution Time: 107.030 ms
(7 rows)
결론: 일반 인덱스를 만들고 통계 정보를 수집한 후 데이터베이스에서 LIKE 문장을 실행할 때 인덱스를 사용할 수 없을 수도 있습니다.작업 클래스가 있는 색인을 만들고 통계 정보를 수집한 후에 LIKE 문장을 실행하면 색인을 정상적으로 사용하는 것을 볼 수 있고 실행 효율이 적지 않게 향상되었다.  
PS:operator class는 Postgresql 새 버전에서 색인을 만드는 새로운 옵션입니다. 색인을 만드는 작업 클래스를 통해 통계 정보를 더욱 정확하게 수집할 수 있도록 합니다. 
통계 정보를 더욱 정확하게 수집하기 위해 우리는 데이터베이스를 초기화하거나 만들 때 Collate를'C'로 설정할 수 있다. 이것도 Postgresql 데이터에서 자주 사용하는 최적화 수단이다.Collate를 C로 설정하는 효과에 대해 테스트해 보겠습니다.

testdb01=# create database testdb02 with TEMPLATE template0  LC_COLLATE='C'  LC_CTYPE ='C' owner highgo;
CREATE DATABASE
 
 
testdb02=# \l+ testdb02
                                           List of databases
   Name   | Owner  | Encoding | Collate | Ctype | Access privileges | Size  | Tablespace | Description
----------+--------+----------+---------+-------+-------------------+-------+------------+-------------
testdb02 | highgo | UTF8     | C       | C     |                   | 59 MB | pg_default |
(1 row)
 
 
testdb02=# create index idx_testliketb01_username on testliketb01(username);
CREATE INDEX
testdb02=# analyze testliketb01 ;
ANALYZE
testdb02=# analyze testliketb01 ;
ANALYZE
testdb02=# analyze testliketb01 ;
ANALYZE
testdb02=#  explain analyze select * from testliketb01 where username like ' %';
                                                                   QUERY PLAN                                                                    
-------------------------------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on testliketb01  (cost=2680.26..9410.67 rows=126033 width=52) (actual time=35.262..99.052 rows=124992 loops=1)
   Filter: ((username)::text ~~ ' %'::text)
   Heap Blocks: exact=5155
   ->  Bitmap Index Scan on idx_testliketb01_username  (cost=0.00..2648.75 rows=126033 width=0) (actual time=33.920..33.920 rows=124992 loops=1)
         Index Cond: (((username)::text >= ' '::text) AND ((username)::text < 'U'::text))
Planning Time: 0.276 ms
Execution Time: 111.578 ms
(7 rows)
결론: 데이터베이스를 만들 때 Collate를 "C"로 설정합니다. 색인이 일반 색인이더라도 LIKE 문장은 색인을 사용하여 조회 효율을 높일 수 있습니다.    

최적화 권장 사항:


1. 데이터베이스를 초기화하거나 만들 때 Collate를 C로 설정합니다.
2. 인덱스를 만들 때 인덱스의 작업 클래스를 지정합니다.(text_pattern_ops, varchar_pattern_ops, bpchar_pattern_ops는 각각 유형 text, varchar,char의 B-tree 인덱스를 지원합니다)
3. 색인을 사용할 수 없는 생각을%X 열에 최적화합니다.%X 를 X% 로 바꾸는 역저장 열을 추가할 수 있습니다.
4. 복잡한 SQL에서 가능한 한 이 인덱스를 호출할 수 있도록 덮어쓰기 인덱스를 만듭니다.
5. 업무 논리를 조정하고 가능한 한 LIKE 문장을 사용하지 않거나 LIKE 문장이 WHERE에 있는 위치를 조정한다.
PostgreSQL 데이터베이스에서 LIKE 문장의 효율을 어떻게 보장하는지에 관한 이 글을 소개합니다. 더 많은 관련 PostgreSQL이 LIKE 문장의 효율을 보장하는 내용은 저희 이전의 문장을 검색하거나 아래의 관련 문장을 계속 훑어보십시오. 앞으로 많은 응원 부탁드립니다!

좋은 웹페이지 즐겨찾기