PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

PostgreSQL sử dụng pg_trgm chậm hơn sau đó quét toàn bộ

tldr:bát quái có thể không tốt trong việc tìm kiếm các mẫu bao gồm một ký tự duy nhất được lặp lại N lần (chẳng hạn như 666666 ) vì chỉ tồn tại 1 bát quái không phải đầu cuối và có thể có tỷ lệ xuất hiện cao trong không gian tìm kiếm.

Khi gin-index được sử dụng, bitmap của các hàng quá lớn để vừa trong bộ nhớ, vì vậy thay vào đó nó lưu trữ tham chiếu đến các trang và cơ sở dữ liệu phải thực hiện quét kiểm tra lại thêm trên các trang này. Nếu số lượng trang được kiểm tra lại ít, việc sử dụng chỉ mục vẫn có lợi, tuy nhiên với số lượng trang được kiểm tra lại cao, chỉ mục hoạt động kém. Điều này được đánh dấu bởi các dòng sau trong kết quả giải thích của bạn

   Recheck Cond: (x ~~* '%666666%'::text)
   Rows Removed by Index Recheck: 36257910
   Heap Blocks: exact=39064 lossy=230594

Vấn đề đặc biệt xảy ra với chuỗi tìm kiếm của bạn, tức là 666666 , liên quan đến dữ liệu thử nghiệm.

nếu bạn chạy select pg_trgm('666666') , bạn sẽ tìm thấy:

        show_trgm        
-------------------------
 {"  6"," 66","66 ",666}
(1 row)

3 bát quái đầu tiên thậm chí sẽ không được tạo trong ngữ cảnh ilike (cách sửa được đề xuất bởi người dùng jjanes ) . Tìm kiếm trên chỉ mục cho ra tất cả các trang có chứa 666 . Bạn có thể xác thực điều này bằng cách chạy truy vấn phân tích giải thích với ... ilike '%666%' và lấy cùng một Heap Blocks đầu ra như trên.

nếu bạn tìm kiếm với mẫu 123456 , bạn sẽ thấy nó hoạt động tốt hơn nhiều, bởi vì nó tạo ra một bộ bát quái lớn hơn để tìm kiếm:

              show_trgm              
-------------------------------------
 {"  1"," 12",123,234,345,456,"56 "}
(1 row)

Trên máy của tôi, tôi nhận được những thứ sau:

|------------------------------------|
| pattern | pages rechecked          |
|         | exact | lossy  | total   |
|------------------------------------|
| 123456  |   600 |        |    600  |
| 666666  | 39454 | 230592 | 270046* |
|    666  | 39454 | 230592 | 270046* |
|------------------------------------|
*this is rougly 85% of the total # of pages used for the table 't'

Đây là kết quả giải thích:

postgres=> explain analyze select * from t where x ~ '123456';
                                                        QUERY PLAN                                                        
--------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on t  (cost=90.75..18143.92 rows=5000 width=22) (actual time=110.962..113.509 rows=518 loops=1)
   Recheck Cond: (x ~ '123456'::text)
   Rows Removed by Index Recheck: 83
   Heap Blocks: exact=600
   ->  Bitmap Index Scan on t_x_idx  (cost=0.00..89.50 rows=5000 width=0) (actual time=110.868..110.868 rows=601 loops=1)
         Index Cond: (x ~ '123456'::text)
 Planning time: 0.703 ms
 Execution time: 113.564 ms
(8 rows)

postgres=> explain analyze select * from t where x ~ '666666';
                                                         QUERY PLAN                                                          
-----------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on t  (cost=54.75..18107.92 rows=5000 width=22) (actual time=137.143..18111.609 rows=462 loops=1)
   Recheck Cond: (x ~ '666666'::text)
   Rows Removed by Index Recheck: 36258389
   Heap Blocks: exact=39454 lossy=230592
   ->  Bitmap Index Scan on t_x_idx  (cost=0.00..53.50 rows=5000 width=0) (actual time=105.962..105.962 rows=593708 loops=1)
         Index Cond: (x ~ '666666'::text)
 Planning time: 0.420 ms
 Execution time: 18111.739 ms
(8 rows)

postgres=> explain analyze select * from t where x ~ '666';
                                                        QUERY PLAN                                                         
---------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on t  (cost=54.75..18107.92 rows=5000 width=22) (actual time=102.813..17285.086 rows=593708 loops=1)
   Recheck Cond: (x ~ '666'::text)
   Rows Removed by Index Recheck: 35665143
   Heap Blocks: exact=39454 lossy=230592
   ->  Bitmap Index Scan on t_x_idx  (cost=0.00..53.50 rows=5000 width=0) (actual time=96.100..96.100 rows=593708 loops=1)
         Index Cond: (x ~ '666'::text)
 Planning time: 0.500 ms
 Execution time: 17300.440 ms
(8 rows)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Thông tin đăng nhập cơ sở dữ liệu vĩnh viễn của Heroku

  2. PostgreSQL - thực hiện hai giao dịch chạy cùng một lúc

  3. Truy vấn đệ quy trong PostgreSQL. LỰA CHỌN *

  4. Nhà cung cấp OleDB / ODBC tốt cho PostgreSQL

  5. Xuất cơ sở dữ liệu PostgreSQL với phpPgAdmin