|
|
|
| 1. Здравствуйте, подскажите ОПТИМАЛЬНЫЙ запрос, который удалял бы записи кроме последних n вставленных. Считаем, что id без пропусков, с автоинкрементом.
2. Не работает такой запрос:
DELETE FROM message WHERE mes_id < (SELECT MAX(mes_id)-50 FROM message)
Не подскажите, почему? Сначала выполняется вложенный запрос, затем идет удаление во внешнем запросе, чтож ему не нравиться то?) | |
|
|
|
|
|
|
|
для: Dante
(01.03.2011 в 21:51)
| | >1. подскажите ОПТИМАЛЬНЫЙ запрос, который удалял бы записи кроме последних n вставленных.
>Считаем, что id без пропусков, с автоинкрементом.
А вот не надо так считать.
Никто над первичными ключами никакие арифметические операции не определял.
Разве что кроме сравнения на больше меньше равно.
Попросите отдельно id 50-й с конца записи.
И отдельным запросом удалите остальные.
Можно подумать, ресурсов больше потребуется.
>Не подскажите, почему?
Потому что нельзя трогать ту самую таблицу, из которой SELECT делаешь.
Костыль в виде вложенного /SELECT-запроса может быть и поможет формально, но всяко выйдет более трудоемко по факту (не смотря на то, что форрмально один запрос) | |
|
|
|
|
|
|
|
для: Dante
(01.03.2011 в 21:51)
| | Запрос должен быть один? Или предварительно допускается подсчет количества записей в таблице (общее количество записей без WHERE-условия будет считаться очень быстро)? | |
|
|
|
|
|
|
|
для: Dante
(01.03.2011 в 21:51)
| | А в MySQL не работают корреклированные запросы в UPDATE и DELETE, вообще они мало где работают. В соседней теме только что обсуждали. | |
|
|
|
|
|
|
|
для: cheops
(01.03.2011 в 22:25)
| | Из-за этого у вас даже не сработает запрос вида (даже если бы конструкция LIMIT была разрешена во вложенных запросах, но до неё дело даже не дойдет, из-за того, что в MySQL нельзя использовать вложенные запросы к удаляемым таблицам)
DELETE FROM message
WHERE mes_id <= (SELECT mes_id AS del_id FROM message
ORDER BY mes_id DESC
LIMIT 50, 1)
|
Можно пойти по пути, который предложил Trianon, обойдя это ограничение при помощи представления (его потребуется создать только один раз)
CREATE VIEW del AS
SELECT mes_id AS del_id
FROM message
ORDER BY mes_id DESC LIMIT 50, 1
|
Т.е. у вас появится виртуальная таблица del, которая всегда будет "знать" номер 51 записи с конца, тогда удалять записи можно будет при помощи следующего запроса
DELETE FROM message
WHERE mes_id <= (SELECT del_id FROM del)
|
| |
|
|
|
|
|
|
|
для: cheops
(01.03.2011 в 22:44)
| | Ясно... Представление то будет. Но просчитывать оно будет каждый раз при запросе как бы это делал и вложенный запрос, наверное...
Ну раз только так, то что ж. Спасибо господа. | |
|
|
|
|
|
|
|
для: Dante
(01.03.2011 в 23:18)
| | >Ясно... Представление то будет. Но просчитывать оно будет каждый раз при запросе как бы это
>делал и вложенный запрос, наверное...
Да, все верно. Однако, если у вас mes_id индексирован - это будет очень "дешевый" по времени и ресурсам запрос, в любом случае, такое решение выгоднее, чем два запроса из клиентской части. | |
|
|
|