Tất cả phụ thuộc ...
-
Giả sử không có quyền truy cập ghi đồng thời đến các bảng có liên quan hoặc bạn có thể phải khóa riêng các bảng hoặc tuyến đường này có thể không dành cho bạn.
-
Xóa tất cả các chỉ mục (có thể ngoại trừ những chỉ mục cần thiết để xóa chính nó).
Tạo lại chúng sau đó. Điều đó thường nhanh hơn nhiều so với các cập nhật gia tăng cho chỉ mục. -
Kiểm tra xem bạn có các trình kích hoạt có thể bị xóa / tắt tạm thời một cách an toàn hay không.
-
Các khóa nước ngoài có tham chiếu đến bảng của bạn không? Chúng có thể bị xóa không? Tạm thời bị xóa?
-
Tùy thuộc vào cài đặt autovacuum của bạn, nó có thể giúp chạy
VACUUM ANALYZE
trước khi hoạt động. -
Một số điểm được liệt kê trong chương liên quan của sổ tay Điền cơ sở dữ liệu cũng có thể được sử dụng, tùy thuộc vào thiết lập của bạn.
-
Nếu bạn xóa các phần lớn của bảng và phần còn lại vừa với RAM, thì cách nhanh nhất và dễ nhất có thể là:
BEGIN; -- typically faster and safer wrapped in a single transaction
SET LOCAL temp_buffers = '1000MB'; -- enough to hold the temp table
CREATE TEMP TABLE tmp AS
SELECT t.*
FROM tbl t
LEFT JOIN del_list d USING (id)
WHERE d.id IS NULL; -- copy surviving rows into temporary table
TRUNCATE tbl; -- empty table - truncate is very fast for big tables
INSERT INTO tbl
SELECT * FROM tmp; -- insert back surviving rows.
-- ORDER BY ? -- optionally order favorably while being at it
COMMIT;
Bằng cách này, bạn không phải tạo lại các khung nhìn, khóa ngoại hoặc các đối tượng phụ thuộc khác. Và bạn sẽ có được một bảng (đã được sắp xếp) nguyên sơ mà không bị phình ra.
Đọc về temp_buffers
cài đặt trong sách hướng dẫn. Phương pháp này nhanh miễn là bảng vừa với bộ nhớ, hoặc ít nhất là gần hết. Trình bao bọc giao dịch bảo vệ khỏi việc mất dữ liệu nếu máy chủ của bạn gặp sự cố khi đang thực hiện thao tác này.
Chạy VACUUM ANALYZE
sau đó. Hoặc VACUUM FULL ANALYZE
nếu bạn muốn mang nó đến kích thước tối thiểu (có khóa riêng). Đối với các bảng lớn, hãy xem xét các lựa chọn thay thế CLUSTER
/ pg_repack
hoặc tương tự:
- Tối ưu hóa phạm vi truy vấn dấu thời gian Postgres
Đối với các bảng nhỏ, DELETE
đơn giản thay vì TRUNCATE
thường nhanh hơn:
DELETE FROM tbl t
USING del_list d
WHERE t.id = d.id;
Đọc Ghi chú phần cho TRUNCATE
trong sách hướng dẫn. Đặc biệt (như Pedro cũng đã chỉ ra trong bình luận của mình):
TRUNCATE
không thể được sử dụng trên một bảng có tham chiếu khóa ngoại từ các bảng khác, trừ khi tất cả các bảng như vậy cũng bị cắt ngắn trong lệnh cùng tên. [...]
Và:
TRUNCATE
sẽ không kích hoạt bất kỳON DELETE
nào các trình kích hoạt có thể tồn tại cho các bảng.