Удалить все записи старше 15 минут - PullRequest
7 голосов
/ 10 июля 2011

У меня есть таблица, которая получает около 10-15 тысяч записей в минуту.Каждый из них помечен текущей отметкой времени при входе.Таблица является таблицей MEMORY, так как потеря данных не имеет значения.

Каждую минуту у меня есть скрипт, который запускает следующий запрос:

DELETE FROM tracker WHERE post_time < DATE_SUB(NOW(), INTERVAL 15 MINUTE)

Этот запрос занимает около1-2 секунды для запуска, что неплохо, но кажется, что этот тип запроса (удаляющий все, что старше X) должен иметь возможность работать намного быстрее при работе с таблицей MEMORY.Он также имеет соответствующий всплеск ЦП, который каждую минуту торчит как больной палец.

Могу ли я сделать какие-либо оптимизации для моего запроса, чтобы выполнить этот запрос более эффективно?

Ответы [ 3 ]

6 голосов
/ 10 июля 2011

Как всегда, вы должны просмотреть план запроса и опубликовать его здесь. Вы делаете это путем выдачи EXPLAIN DELETE FROM tracker WHERE post_time < DATE_SUB(NOW(), INTERVAL 15 MINUTE)

Теперь проблема, вероятно, в том, что запрос DELETE не может использовать индекс и должен проходить по всем строкам.

Даже если у вас уже есть индекс на post_time, он, скорее всего, не будет использоваться, так как по умолчанию индексы в таблицах MEMORY являются хеш-индексами. Хеш-индексы могут использоваться только для проверок на равенство, а не диапазоны, такие как post_time < DATE_SUB(NOW(), INTERVAL 15 MINUTE)

Создайте индекс BTREE для вашего столбца post_time,

CREATE INDEX post_time_idx ON tracker (post_time) USING BTREE;
1 голос
/ 10 июля 2011

Если ваша таблица никогда не содержит данных за 15 минут, вы можете использовать меньший тип данных, чем DATETIME, для хранения ваших временных меток.В зависимости от степени детализации, которая вас интересует, вы можете использовать очень маленький тип данных ... С SMALLINT вы можете хранить «минуты с полуночи».Если вы готовы потерять еще большую степень детализации, вы можете использовать TINYINT для 15-минутной степени детализации.Конечно, это требует немного более сложной логики для обработки дел «сразу после полуночи» ...

DELETE FROM tracker
WHERE (
    EXTRACT(DAY_MINUTE FROM NOW()) > 15
    AND post_time < EXTRACT(DAY_MINUTE FROM NOW())
) OR (
    post_time < EXTRACT(DAY_MINUTE FROM NOW()) < 15
    AND post_time < EXTRACT(DAY_MINUTE FROM NOW()+60)
)

Преимущество состоит в том, что данные, которые вы должны прочитать и сравнить, намного меньше, поэтому их можно обрабатыватьБыстрее.Это имело бы большее значение, если бы вы хранили свои данные на диске, где дисковый ввод-вывод пропорционально намного важнее пропускной способности вашей памяти.

Кроме того, для таблицы, содержащей только 10-15k строк, и правильнойИндекс, я сомневаюсь, что это будет иметь какое-либо заметное значение - будь то на диске или в памяти.

1 голос
/ 10 июля 2011

Сделать индекс на post_time.Если строки, соответствующие post_time < DATE_SUB(NOW(), INTERVAL 15 MINUTE), составляют небольшую часть всей таблицы, это должно значительно ускорить процесс.

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