How to optimally delete records referenced from another table in PostgreSQL?

When deleting records from a table that are referenced by other tables in PostgreSQL, there are several ways to ensure that the deletion is performed optimally and does not violate any foreign key constraints. Here are some common approaches:

  1. Cascading Deletion: This approach automatically deletes any rows in the referencing tables that reference the rows being deleted. To enable cascading deletion, you can add the ON DELETE CASCADE option to the foreign key constraint definition.

For example, suppose you have two tables, orders and order_items, with a foreign key constraint that references orders(order_id) from order_items(order_id). If you want to delete all orders with an order_date earlier than a certain date and also delete their associated order items, you can use the following SQL command:

DELETE FROM orders WHERE order_date < ‘2022-01-01’ CASCADE;

This will delete all orders with an order_date earlier than 2022-01-01 and also delete all corresponding rows from the order_items table.

  1. Use Subqueries: Another approach is to use subqueries to identify the rows to be deleted and their corresponding rows in the referencing tables. You can then delete the rows from the referencing tables first, and then delete the rows from the main table.

For example, suppose you have two tables, orders and order_items, with a foreign key constraint that references orders(order_id) from order_items(order_id). If you want to delete all orders with an order_date earlier than a certain date and also delete their associated order items, you can use the following SQL commands:

DELETE FROM order_items WHERE order_id IN (SELECT order_id FROM orders WHERE order_date < ‘2022-01-01’);

DELETE FROM orders WHERE order_date < ‘2022-01-01’;

This will first delete all corresponding rows from the order_items table, and then delete all orders with an order_date earlier than 2022-01-01.

  1. Disable Constraints: Another approach is to temporarily disable the foreign key constraints before deleting the rows, and then re-enable the constraints after the deletion is complete.

For example, you can disable a foreign key constraint by using the following SQL command:

ALTER TABLE order_items DROP CONSTRAINT order_items_order_id_fkey;

You can then delete the rows from the main table, and then re-enable the foreign key constraint by using the following SQL command:

ALTER TABLE order_items ADD CONSTRAINT order_items_order_id_fkey FOREIGN KEY (order_id) REFERENCES orders(order_id);

Note that this approach should be used with caution, as disabling constraints can potentially lead to data integrity issues if the deletion is not performed correctly.

Overall, the best approach to deleting records referenced from another table in PostgreSQL depends on the specific use case and data model. Cascading deletion and subqueries are generally safe and efficient approaches while disabling constraints should be used with caution and only in certain cases.

Conclusion

When deleting records in PostgreSQL that are referenced by other tables, it’s crucial to choose the right approach to maintain data integrity and optimize performance. Cascading deletion and subqueries offer safe and efficient methods for handling such deletions. However, disabling constraints can be risky and should be used cautiously, ensuring data integrity throughout the deletion process.

About Shiv Iyer 452 Articles
Open Source Database Systems Engineer with a deep understanding of Optimizer Internals, Performance Engineering, Scalability and Data SRE. Shiv currently is the Founder, Investor, Board Member and CEO of multiple Database Systems Infrastructure Operations companies in the Transaction Processing Computing and ColumnStores ecosystem. He is also a frequent speaker in open source software conferences globally.