Sloooow запрос на сборку мусора - PullRequest
0 голосов
/ 25 января 2012

У меня есть две таблицы: одна хранит сессии пользователя, а другая - данные корзины покупок.sessions имеет столбец cart_id, который соответствует id в таблице carts.Я пытаюсь запустить сборку мусора на моих сеансах на основе базы данных.Сначала я удаляю сеансы с истекшим сроком действия:

DELETE FROM sessions WHERE expires < NOW();

Затем я удаляю корзины, которые теперь являются осиротевшими, иными словами, не существует сеанса, чей cart_id соответствует этому.

DELETE `carts`
FROM `carts`
LEFT OUTER JOIN `sessions`
ON `carts`.`id` = `sessions`.`cart_id`
WHERE `sessions`.`cart_id` IS NULL

Последний запрос действительно медленный, примерно 60 секунд вроде медленного.

Я пробовал вместо этого:

DELETE `cart`
FROM `cart`
WHERE `cart`.`id` NOT IN (SELECT `cart_id` FROM `sessions`)

Что тоже медленно.Есть указатели?

Ответы [ 2 ]

2 голосов
/ 25 января 2012

Вы можете перевернуть это. Пусть каждая корзина ссылается на идентификатор сеанса через FOREIGN KEY и задает ON DELETE CASCADE. Таким образом, при удалении строки в сеансе корзины, связанные с ней, также удаляются.

CREATE TABLE session (session_id INT NOT NULL,
                      expires DATE NOT NULL,
                     PRIMARY KEY (session_id),
                     INDEX expires_index (expires)
) ENGINE=INNODB;                          

CREATE TABLE cart (id INT, 
                   session_id INT,
                   INDEX session_index (session_id),
                   FOREIGN KEY (session_id) REFERENCES session(session_id) ON DELETE CASCADE
) ENGINE=INNODB;

Если вы обнаружите, что удаление всех просроченных корзин занимает слишком много времени делайте меньшее удаление чаще с limit .

DELETE FROM session WHERE expires < NOW() ORDER BY expires LIMIT 10;
1 голос
/ 25 января 2012

Убедитесь, что столбцы sessions.expires и sessions.cart_id проиндексированы.

Если у вас сайт с большим трафиком и вы добавляете много тележек / сеансов, операция удаления будет медленнее из-запараллелизм.

Последняя отправленная вами операция всегда будет очень медленной, если у вас много сеансов (при закрытии IN нужно будет сравнивать каждый идентификатор один за другим).

Правило большого пальцапри использовании оператора IN: количество значений IN должно быть относительно небольшим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...