2014-12-18 3 views
0

У нас есть таблица, в которой хранятся адреса клиентов. Эти адреса затем используются в нескольких других таблицах всей системы, чтобы связать адрес с порядком. Мы хотим периодически удалять все старые адреса, которые не были использованы в заказе более года.оптимизировать удаление ссылок на несколько таблиц

address table: 
id | address | created_at 
1 | 1234 Rd | 2011-03-12 12:45:09 
2 | 2345 Rd | 2012-04-12 13:39:19 
3 | 3456 Rd | 2012-05-12 14:33:12 
4 | 4567 Rd | 2014-12-12 15:19:54 

customer_order table: 
id | address_id | created_at 
1 | 1   | 2011-03-12 12:50:00 
2 | 2   | 2012-04-12 12:55:00 
3 | 2   | 2014-09-12 12:50:00 

group_order table: 
id | address_id | created_at 
1 | 2   | 2012-07-12 19:23:56 
2 | 3   | 2012-10-19 14:36:28 

Таким образом, мы бы хотели, чтобы удалить адрес с идентификаторами 1 и 3, так как они не были использованы в порядке в течение года. Мы будем хранить адрес # 4, поскольку он был создан недавно, а # 2 использовался в течение прошлого года, поэтому его не следует удалять.

То, что я в настоящее время:

DELETE FROM address WHERE created_at < DATE_SUB(NOW(), INTERVAL 365 DAY) AND id NOT IN (
    SELECT address_id FROM group_order WHERE created_at > DATE_SUB(NOW(), INTERVAL 365 DAY) 
    UNION DISTINCT 
    SELECT address_id FROM customer_order WHERE created_at > DATE_SUB(NOW(), INTERVAL 365 DAY) 
) 

Однако мой адрес таблицы содержит 800000+ строк, customer_order содержит 2.5M + строк, group_order содержит 100000+ строки и есть другая таблица, которая содержит несколько сотен строк, которые Я также должен добавить. Поэтому удаление занимает много времени (сам подзапрос возвращает 400000+ строк за 4 секунды, но удаление занимает гораздо больше времени).

Есть ли более эффективный способ сделать это?

ответ

0

я в конечном итоге делает это как 2 отдельных запросов с помощью PHP, чтобы передать результаты подзапроса во внешний запрос (выборки каждого из идентификаторов, то Implode в НЕ В списке во внешнем запросе.

Я надеялся, что mysql будет достаточно умным, чтобы увидеть, что подзапрос не зависит от внешнего запроса и поэтому просто запускает его один раз и кэширует результаты, но я предполагаю, что он выполнял подзапрос для каждой строки из внешнего запроса , что приводит к длительному времени (~ 4 секунды в подзапросе * ~ 800000).

Смежные вопросы