CLUSTER
Nếu bạn định sử dụng CLUSTER
, cú pháp được hiển thị không hợp lệ.
tạo vé CLUSTER USING ticket_1_idx;
Chạy một lần:
CLUSTER ticket USING ticket_1_idx;
Cái này có thể giúp ích rất nhiều cho các tập kết quả lớn hơn. Không quá nhiều đối với một hàng được trả về.
Postgres ghi nhớ chỉ mục nào sẽ sử dụng cho các cuộc gọi tiếp theo. Nếu bảng của bạn không ở chế độ chỉ đọc, hiệu ứng sẽ giảm dần theo thời gian và bạn cần chạy lại vào những khoảng thời gian nhất định:
CLUSTER ticket;
Có thể chỉ trên các phân vùng dễ bay hơi. Xem bên dưới.
Tuy nhiên , nếu bạn có nhiều bản cập nhật, hãy CLUSTER
(hoặc VACUUM FULL
) thực sự có thể không tốt cho hiệu suất. Lượng phồng phù hợp cho phép CẬP NHẬT
để đặt các phiên bản hàng mới trên cùng một trang dữ liệu và tránh nhu cầu mở rộng vật lý tệp cơ bản trong Hệ điều hành quá thường xuyên. Bạn có thể sử dụng FILLFACTOR
được điều chỉnh cẩn thận để tận dụng tối đa cả hai thế giới:
- Hệ số lấp đầy cho một chỉ số tuần tự là PK
pg_repack
CLUSTER
có một ổ khóa độc quyền trên bàn, đây có thể là một vấn đề trong môi trường nhiều người dùng. Trích dẫn hướng dẫn sử dụng:
Khi một bảng đang được nhóm, một
TRUY CẬP ĐỘC QUYỀN
khóa được mua lại trên nó. Điều này ngăn cản bất kỳ hoạt động cơ sở dữ liệu nào khác (cả đọc và ghi ) từ khi thao tác trên bàn cho đến khiCLUSTER
đã kết thúc.
Tôi nhấn mạnh đậm. Xem xét pg_repack
thay thế :
Không giống như
CLUSTER
vàVACUUM FULL
nó hoạt động trực tuyến mà không cần giữ khóa độc quyền trên các bảng được xử lý trong quá trình xử lý. pg_repack là hệ số để khởi động, với hiệu suất tương đương với việc sử dụngCLUSTER
trực tiếp.
và:
pg_repack cần có một khóa riêng khi kết thúc tổ chức lại.
Phiên bản 1.3.1 hoạt động với:
PostgreSQL 8.3, 8.4, 9.0, 9.1, 9.2, 9.3, 9.4
Phiên bản 1.4.2 hoạt động với:
PostgreSQL 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 10
Truy vấn
Truy vấn đủ đơn giản để không gây ra bất kỳ vấn đề hiệu suất nào.
Tuy nhiên, một từ về tính đúng đắn : GIỮA
cấu trúc bao gồm biên giới. Truy vấn của bạn chọn tất cả ngày 19 tháng 12, cộng với hồ sơ từ ngày 20 tháng 12, 00:00 giờ. Đó là một điều cực kỳ khó xảy ra yêu cầu. Rất có thể, bạn thực sự muốn:
SELECT *
FROM ticket
WHERE created >= '2012-12-19 0:0'
AND created < '2012-12-20 0:0';
Hiệu suất
Trước hết, bạn hỏi:
Tại sao nó lại chọn quét tuần tự?
EXPLAIN
của bạn đầu ra hiển thị rõ ràng một Quét chỉ mục , không phải quét bảng tuần tự. Chắc có một sự hiểu lầm nào đó.
Nếu bạn bị thúc ép để đạt được hiệu suất tốt hơn, bạn có thể cải thiện mọi thứ. Nhưng thông tin cơ bản cần thiết không có trong câu hỏi. Các tùy chọn có thể có bao gồm:
-
Bạn chỉ có thể truy vấn các cột bắt buộc thay vì
*
để giảm chi phí chuyển nhượng (và có thể là các lợi ích hiệu suất khác). -
Bạn có thể xem xét phân vùng và đặt các lát thời gian thực tế vào các bảng riêng biệt. Thêm chỉ mục vào các phân vùng nếu cần.
-
Nếu phân vùng không phải là một tùy chọn, thì một kỹ thuật khác có liên quan nhưng ít xâm phạm hơn sẽ là thêm một hoặc nhiều chỉ mục một phần .
Ví dụ:nếu bạn chủ yếu truy vấn tháng hiện tại , bạn có thể tạo chỉ mục từng phần sau:CREATE INDEX ticket_created_idx ON ticket(created) WHERE created >= '2012-12-01 00:00:00'::timestamp;
TẠO
một chỉ mục mới ngay trước đầu tháng mới. Bạn có thể dễ dàng tự động hóa tác vụ bằng cron job. Tùy chọnDROP
chỉ mục một phần cho những tháng cũ sau đó. -
Giữ tổng chỉ mục bổ sung cho
CLUSTER
(không thể hoạt động trên các chỉ mục từng phần). Nếu các bản ghi cũ không bao giờ thay đổi, thì việc phân vùng bảng sẽ giúp ích rất nhiều cho công việc này, vì bạn chỉ cần phân cụm lại các phân vùng mới hơn. .
Nếu bạn kết hợp hai bước cuối cùng, hiệu suất sẽ rất tuyệt vời.
Khái niệm cơ bản về hiệu suất
Bạn có thể thiếu một trong những điều cơ bản. Tất cả các lời khuyên về hiệu suất thông thường đều được áp dụng:
- https://wiki.postgresql.org/wiki/Slow_Query_Questions
- https://wiki.postgresql.org/wiki/Performance_Optimization