Я знаю, что воскрешаю довольно старый вопрос, но недавно я столкнулся с этой проблемой, но мне нужно что-то, что хорошо масштабируется до . Существующих данных о производительности не было, и, поскольку этому вопросу было уделено немало внимания, я решил опубликовать то, что нашел.
На самом деле работали следующие решения: метод двойного подзапроса Алекса Барретта / NOT IN
(аналогичный 1009 * Билла Карвина) и 1011 ** 1012 Кассну * метод.
К сожалению, оба приведенных выше метода создают очень большие промежуточные временные таблицы, и производительность быстро снижается, так как количество удаляемых записей не становится большим.
То, на чем я остановился, использует двойной подзапрос Алекса Барретта (спасибо!), Но использует <=
вместо NOT IN
:
DELETE FROM `test_sandbox`
WHERE id <= (
SELECT id
FROM (
SELECT id
FROM `test_sandbox`
ORDER BY id DESC
LIMIT 1 OFFSET 42 -- keep this many records
) foo
)
Он использует OFFSET
для получения идентификатора N -й записи и удаляет эту запись и все предыдущие записи.
Поскольку заказ уже является предположением этой проблемы (ORDER BY id DESC
), <=
идеально подходит.
Это намного быстрее, поскольку временная таблица, сгенерированная подзапросом, содержит только одну запись вместо N записей.
Контрольный пример
Я проверил три метода работы и новый метод, описанный выше, в двух тестовых случаях.
В обоих тестовых примерах используется 10000 существующих строк, в то время как в первом тесте хранится 9000 (удаляется самая старая 1000), а во втором - 50 (удаляется самая старая 9950).
+-----------+------------------------+----------------------+
| | 10000 TOTAL, KEEP 9000 | 10000 TOTAL, KEEP 50 |
+-----------+------------------------+----------------------+
| NOT IN | 3.2542 seconds | 0.1629 seconds |
| NOT IN v2 | 4.5863 seconds | 0.1650 seconds |
| <=,OFFSET | 0.0204 seconds | 0.1076 seconds |
+-----------+------------------------+----------------------+
Что интересно, метод <=
обеспечивает лучшую производительность по всем направлениям, но на самом деле, чем больше вы сохраняете, тем лучше.