Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 1
Привет, уважаемые.
Немного детализирую ситуацию.
Неактивен
2. Сортировка происходит до LIMIT, и ей подвергаются разные наборы (из-за вставок). Поэтому алгоритм сортировки дает разный ответ.
1. Решить можно
CREATE TEMPORARY TABLE myworktable select ... order by DT,ID limit ...;
SELECT * FROM myworktable;
обработка
DELETE FROM T USING T t INNER JOIN myworktable w WHERE t.DT = w.DT AND t.ID=w.ID AND еще условия достаточные для уникальности;
DROP TEMPORARY TABLE myworktable;
Неактивен
rgbeast написал:
2. Сортировка происходит до LIMIT, и ей подвергаются разные наборы (из-за вставок). Поэтому алгоритм сортировки дает разный ответ.
Спасибо за ответ.
Всё равно странно, т.к. достоверно известно что вставка никогда не перекрывала (по значению индекса)
порцию для удаления. Видимо дело в том, что order by для select обрабатывается
по иному, чем для delete. Может дело в том, что в каких-то конкретных ситуациях
(размер limit, базы, дырок и т.п.) ключ не используется.
Я предполагаю, что на таблице с уникальным индексом таких проблем бы не было.
rgbeast написал:
1. Решить можно
CREATE TEMPORARY TABLE myworktable select ... order by DT,ID limit ...;
SELECT * FROM myworktable;
обработка
DELETE FROM T USING T t INNER JOIN myworktable w WHERE t.DT = w.DT AND t.ID=w.ID AND еще условия достаточные для уникальности;
DROP TEMPORARY TABLE myworktable;
Хм., интересно, сколько же будет длится DELETE с INNER-ом.
К тому же я хотел-бы (для оптимизации)
while (условие)
select ... limit N offset M
а потом уже одним delete ... total_fetched
Неактивен
С уникальным индексом сортировка дает однозначный ответ. А с неуникальным неоднозначный, а так как дерево индекса может менять местами ветви при вставке. Хотя может быть действительно есть различия в обработке при SELECT и DELETE.
Вы не сказали сколько записей обрабатывается за раз. DELETE + INNER будет использовать индекс, поэтому не должен работать медленно.
Один общий DELETE не даст особой оптимизации. При условии, что в базу идет постоянная вставка, лучше несколько DELETE поменьше, чем один большой.
Есть еще один способ: делать выборку так, чтобы включить все записи с данными DT и ID, тогда сортировка будет однозначной.
Неактивен
rgbeast написал:
Вы не сказали сколько записей обрабатывается за раз. DELETE + INNER будет использовать индекс, поэтому не должен работать медленно.
Один общий DELETE не даст особой оптимизации. При условии, что в базу идет постоянная вставка, лучше несколько DELETE поменьше, чем один большой.
Есть еще один способ: делать выборку так, чтобы включить все записи с данными DT и ID, тогда сортировка будет однозначной.
Записей всего ~ 2млн и select без limit - увы.
Для where нет условия на момент выборки,
т.к. порция на удаление заранее не известна, определяется по-ходу в обработке.
Удаляется всегда по-разному, мож. 5 тыс. а мож. 50тыс.
Кучка мелких delete(например с 10-ток по 1000) выполняется в 5-7 раз медленнее чем один (10000, продолжая пример).
Подтверждено опытом. Причём на эту диспропорцию не сильно влияет используется ключ или нет
и влез весь индекс в память или нет. Видимо размер базы вносит свои коррективы.
explain select всегда кажет использование индекса.
Подумываю добавить автоинкримент, чтобы составной dt1, id, autoinc сделать уникальным.
Нужно только поверить что уникальность индекса по всем полям которого order by решит проблему
Неактивен
Неоднозначность у Вас возникает только на хвосте выборке - для последнего значения пары (DT, ID). Просто не обрабатывайте и не удаляйте строки с последними в выборке значениями DT,ID, тогда будет однозначность.
Еще есть вариант использования двух таблиц. Пусть будет некая переменная, которая задает в какую таблицу писать (эта переменная может хранится в отдельной таблице). Сначала она 0, скрипт пишет в table0. Вы запускаете обработчик - он выставляет переменную в 1 и запись теперь идет в table1. Делает SELECT * FROM table0, а потом просто TRUNCATE table0. Затем обработчик выставляет переменную в 0 и обрабатывает все в table1. Вы избавлены вообще от операции DELETE.
Неактивен
Страниц: 1