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

Thêm ràng buộc datetime vào chỉ mục một phần nhiều cột PostgreSQL

Bạn nhận được một ngoại lệ bằng cách sử dụng now() bởi vì hàm không IMMUTABLE (rõ ràng) và trích dẫn hướng dẫn sử dụng :

Tôi thấy có hai cách để sử dụng chỉ mục từng phần (hiệu quả hơn nhiều):

1. Chỉ mục một phần với điều kiện sử dụng hằng số ngày:

CREATE INDEX queries_recent_idx ON queries_query (user_sid, created)
WHERE created > '2013-01-07 00:00'::timestamp;

Giả định created thực sự được định nghĩa là timestamp . Sẽ không hoạt động nếu cung cấp timestamp hằng số cho một timestamptz cột (timestamp with time zone ). Diễn viên từ timestamp đến timestamptz (hoặc ngược lại) phụ thuộc vào cài đặt múi giờ hiện tại và không thể thay đổi . Sử dụng một hằng số kiểu dữ liệu phù hợp. Hiểu kiến ​​thức cơ bản về dấu thời gian có / không có múi giờ:

Thả và tạo lại chỉ số đó vào những giờ có lưu lượng truy cập thấp, có thể với một công việc cron hàng ngày hoặc hàng tuần (hoặc bất cứ điều gì đủ tốt cho bạn). Tạo chỉ mục khá nhanh, đặc biệt là một chỉ mục tương đối nhỏ. Giải pháp này cũng không cần thêm bất kỳ thứ gì vào bảng.

Giả sử không có quyền truy cập đồng thời vào bảng, việc tạo chỉ mục tự động có thể được thực hiện với một chức năng như sau:

CREATE OR REPLACE FUNCTION f_index_recreate()
  RETURNS void
  LANGUAGE plpgsql AS
$func$
BEGIN
   DROP INDEX IF EXISTS queries_recent_idx;
   EXECUTE format('
      CREATE INDEX queries_recent_idx
      ON queries_query (user_sid, created)
      WHERE created > %L::timestamp'
    , LOCALTIMESTAMP - interval '30 days');  -- timestamp constant
--  , now() - interval '30 days');           -- alternative for timestamptz
END
$func$;

Gọi:

SELECT f_index_recreate();

now() (như bạn đã có) tương đương với CURRENT_TIMESTAMP và trả về timestamptz . Truyền tới timestamp với now()::timestamp hoặc sử dụng LOCALTIMESTAMP thay vào đó.

db <> fiddle tại đây
sqlfiddle

Nếu bạn phải đối phó với truy cập đồng thời vào bảng, sử dụng DROP INDEX CONCURRENTLYCREATE INDEX CONCURRENTLY . Nhưng bạn không thể gói các lệnh này thành một hàm vì theo tài liệu :

Vì vậy, với hai giao dịch riêng biệt :

CREATE INDEX CONCURRENTLY queries_recent_idx2 ON queries_query (user_sid, created)
WHERE  created > '2013-01-07 00:00'::timestamp;  -- your new condition

Sau đó:

DROP INDEX CONCURRENTLY IF EXISTS queries_recent_idx;

Theo tùy chọn, đổi tên thành tên cũ:

ALTER INDEX queries_recent_idx2 RENAME TO queries_recent_idx;

2. Chỉ mục một phần với điều kiện trên thẻ "đã lưu trữ"

Thêm một archived gắn thẻ vào bảng của bạn:

ALTER queries_query ADD COLUMN archived boolean NOT NULL DEFAULT FALSE;

UPDATE cột trong khoảng thời gian bạn chọn để "gỡ bỏ" các hàng cũ hơn và tạo chỉ mục như:

CREATE INDEX some_index_name ON queries_query (user_sid, created)
WHERE NOT archived;

Thêm một điều kiện phù hợp vào các truy vấn của bạn (ngay cả khi nó có vẻ thừa) để cho phép nó sử dụng chỉ mục. Kiểm tra bằng EXPLAIN ANALYZE liệu trình lập kế hoạch truy vấn có bắt kịp không - nó có thể sử dụng chỉ mục cho các truy vấn vào một ngày mới hơn. Nhưng nó sẽ không hiểu các điều kiện phức tạp hơn không khớp chính xác.

Bạn không phải thả và tạo lại chỉ mục, mà là UPDATE trên bảng có thể đắt hơn giải trí lập chỉ mục và bảng lớn hơn một chút.

Tôi sẽ đi với đầu tiên tùy chọn (tái tạo chỉ mục). Trên thực tế, tôi đang sử dụng giải pháp này trong một số cơ sở dữ liệu. Lần thứ hai phải cập nhật tốn kém hơn.

Cả hai giải pháp đều giữ được tính hữu dụng của chúng theo thời gian, hiệu suất từ ​​từ giảm xuống do nhiều hàng lỗi thời hơn được đưa vào chỉ mục.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Nhận giá trị nối tiếp mặc định sau khi INSERT bên trong PL / pgSQL

  2. Xóa một bảng trong PostgreSQL mà không xóa một chuỗi được liên kết

  3. Thử nghiệm Mocha PostgreSQL với Knex đang cho tôi lỗi MigrationLocked

  4. SQL tiếp tục thực thi các truy vấn sau khi vi phạm khóa trùng lặp

  5. Tổng quan về các thay đổi chỉ mục trong PostgreSQL 11