Учитывая, что у вас есть только одна таблица access_log, просто выбрать эти записи. Вам придется вытащить их в клиентскую программу, а затем подтолкнуть их к другой таблице.
SELECT *
FROM access_log
WHERE logtime >= CURRENT_DATE() - INTERVAL 1 DAY
AND logtime < CURRENT_DATE();
Тогда
DELETE
FROM access_log
WHERE logtime >= CURRENT_DATE() - INTERVAL 1 DAY
AND logtime < CURRENT_DATE();
(Избегайте использования BETWEEN
для выбора диапазонов времени/даты;. Он делает неправильные вещи в конце диапазона вы выбираете)
Но это немного свинья. Во-первых, эта таблица должна использовать механизм хранения MyISAM, а не InnoDB, поэтому вы не обременены транзакционными издержками.
Если это InnoDB, и вы не можете изменить это, вам может потребоваться написать программу для чтения, а затем удалить данные в более мелкие куски. Например, один из фрагментов может быть:
SELECT *
FROM access_log
WHERE logtime >= CURRENT_DATE() - INTERVAL 1 DAY + INTERVAL 1 HOUR
AND logtime < CURRENT_DATE() - INTERVAL 1 DAY + INTERVAL 2 HOUR
Или, если вы можете позволить себе второй или два простоя в полночь вы можете переименовать таблицу access_log в yesterday_access_log, и создать новую на сегодняшний день. Затем вы можете сэкономить вчерашний стол, не сталкиваясь с производительностью.
Вы можете сделать эту операцию в полночь лог-своп с суждениями типа:
CREATE TABLE `access_log_new` (
/* whatever columns you have in your access_log table, I made this stuff up */
`log_id` INT(11) NOT NULL AUTO_INCREMENT,
`item` VARCHAR(255) NOT NULL,
`logtime` TIMESTAMP NOT NULL ,
PRIMARY KEY (`log_id`)
) ENGINE=MYISAM;
DROP TABLE access_log_old;
RENAME TABLE access_log TO access_log_old;
RENAME TABLE access_log_new TO access_log;
Два последних утверждения здесь, то RENAME TABLE
заявления, очень быстро. Крошечный период времени, когда нет таблицы access_log, но это намного меньше секунды. Идея заключается в том, чтобы все хорошо настроить, а затем быстро перевернуть файлы журнала.
Это может быть действительно хорошая стратегия; это позволит вам использовать механизм хранения ARCHIVE с дешевой записью и дорогостоящим поиском для вашей таблицы live access_log.
Если у вас есть выбор для реструктуризации вашей таблицы access_log, вы можете разделить его на день, чтобы вы могли просто поменять ежедневные таблицы разделов. Но это более длинная тема.
Олли, спасибо за ваш вклад и дополнительные идеи ... Мне нравится концепция разделения таблицы на день. Я действительно рассматривал использование двух таблиц, но я не могу позволить себе время простоя (в течение некоторого времени в течение дня происходит замедление, но я все равно потеряю тысячи записей); Я также подумал об обмене между таблицами _0 и _1 на основе даты mod "(time()/(24 * 60 * 60))% 2", однако это также было бы свингом производительности, но на стороне веб-сервера (проверьте мод с каждой вставкой). – Kate
WHERE logtime> = CURRENT_DATE() - INTERVAL 1 DAY И logtime
AdrianBR
Это не эквивалентное выражение, @AdrianBR, если только сравниваемый столбец «date» не имеет времени, кроме полночь в нем. Если вы имеете в виду 'DATE (logtime)' использование функции, это приведет к победе над использованием индекса в столбце 'logtime', что плохо в большой таблице. –