A client's database that had over 500K records in this table was causing a serious slowdown. Here was my approach.
Make backups!
No, seriously. Make backups using mysqldump
.
Here's What I Did - After Making A Backup
1. Find the tables that reference sales_flat_quote
.
mysql> SELECT TABLE_NAME, COLUMN_NAME FROM information_schema.KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_NAME = 'sales_flat_quote' AND REFERENCED_COLUMN_NAME = 'entity_id' AND TABLE_SCHEMA = '[your-magento-db-name]';
This is why this step was so important:
+--------------------------+-------------+
| TABLE_NAME | COLUMN_NAME |
+--------------------------+-------------+
| sales_flat_quote_address | quote_id |
| sales_flat_quote_item | quote_id |
| sales_flat_quote_payment | quote_id |
| task_system | quote_id |
+--------------------------+-------------+
There might be extensions that also reference it. And in my client's case, there was! Furthermore, it was a cascade FK. If we had deleted that, it would have deleted all the records in their task_system
table.
We updated the task_system
.quote_id
to DEFAULT NULL
and then the FK to ON DELETE SET_NULL
.
Now we're safe to do this:
2. Delete all carts/quotes over 60 days old:
Kudos to: Fiasco Labs
START TRANSACTION;
DELETE FROM sales_flat_quote WHERE updated_at < DATE_SUB(Now(),INTERVAL 60 DAY) LIMIT 100;
COMMIT;
OR, try this if you want to keep quotes referenced by the sales_flat_order
table:
Kudos to: Fiasco Labs and Styopchik
START TRANSACTION;
DELETE FROM sales_flat_quote WHERE entity_id NOT IN (SELECT quote_id FROM sales_flat_order) AND `updated_at` < DATE_SUB(Now(),INTERVAL 60 DAY) LIMIT 100;
COMMIT;
Note: The LIMIT 100
here as this could completely lock up your database. Do it in batches.
2. Don't Assume!
Do not assume all is well.
mysql> SELECT COUNT(*) FROM sales_flat_quote_item;
+----------+
| COUNT(*) |
+----------+
| 21 |
+----------+
1 row in set (0.03 sec)
So we have some orphaned data. You need to get rid of that by JOINING the sales_flat_quote_
tables to the sales_flat_quote
table where quote_id IS NULL. That's out of scope for this answer. just Google "deleting mysql orphaned records". Make backups!