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

Cách tốt nhất để xóa hàng triệu hàng theo ID

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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tạo nhiều phiên bản Postgres trên cùng một máy

  2. Các phương pháp hay nhất về ghi nhật ký kiểm tra PostgreSQL

  3. Không thể CHỌN từ mệnh đề CẬP NHẬT TRẢ LẠI trong postgres

  4. Số lượng SQL có điều kiện

  5. Gấu trúc ghi khung dữ liệu vào lược đồ postgresql khác