SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 18.02.2010 16:56:42

avreg
Участник
Зарегистрирован: 18.02.2010
Сообщений: 7

select и delete c "order by F limit N" используют разные наборы данных

Привет, уважаемые.

Немного детализирую ситуацию.


create table ... (
  DT datetime NOT NULL,
  ID smallint unsigned NOT NULL,
  ...
  key IDX (DT, ID)
) engine=MyISAM;
 


Таблица - свалка ссылок, в которую один процесс непрерывно добавляет,
другой периодически должен чистить старые записи некоторыми порциями.

Индекс IDX не уникальный с этим сочетанием полей,
а с другим уникальным сочетанием полей - слишком жирно получается.

Удаляю так:

select ... order by DT,ID limit ...
... обработка ...
delete ... order by DT,ID limit ...

Заметил что после нескольких проходов select и delete оперируют разными наборами данными и возникает рассинхронизация.

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

Что хотелось бы у вас спросить:
1) можно ли как-то эту задачу решить без добавления автоинкремента и where по нему? (основной вопрос)
2) собственно почему разные наборы? (дополнительный)

Неактивен

 

#2 18.02.2010 17:51:21

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: select и delete c "order by F limit N" используют разные наборы данных

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;

Неактивен

 

#3 18.02.2010 18:27:06

avreg
Участник
Зарегистрирован: 18.02.2010
Сообщений: 7

Re: select и delete c "order by F limit N" используют разные наборы данных

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

Неактивен

 

#4 18.02.2010 18:42:37

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: select и delete c "order by F limit N" используют разные наборы данных

С уникальным индексом сортировка дает однозначный ответ. А с неуникальным неоднозначный, а так как дерево индекса может менять местами ветви при вставке. Хотя может быть действительно есть различия в обработке при SELECT и DELETE.

Вы не сказали сколько записей обрабатывается за раз. DELETE + INNER будет использовать индекс, поэтому не должен работать медленно.

Один общий DELETE не даст особой оптимизации. При условии, что в базу идет постоянная вставка, лучше несколько DELETE поменьше, чем один большой.

Есть еще один способ: делать выборку так, чтобы включить все записи с данными DT и ID, тогда сортировка будет однозначной.

Неактивен

 

#5 18.02.2010 18:58:25

avreg
Участник
Зарегистрирован: 18.02.2010
Сообщений: 7

Re: select и delete c "order by F limit N" используют разные наборы данных

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 решит проблему smile

Неактивен

 

#6 18.02.2010 19:15:38

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: select и delete c "order by F limit N" используют разные наборы данных

Неоднозначность у Вас возникает только на хвосте выборке - для последнего значения пары (DT, ID). Просто не обрабатывайте и не удаляйте строки с последними в выборке значениями DT,ID, тогда будет однозначность.

Еще есть вариант использования двух таблиц. Пусть будет некая переменная, которая задает в какую таблицу писать (эта переменная может хранится в отдельной таблице). Сначала она 0, скрипт пишет в table0. Вы запускаете обработчик - он выставляет переменную в 1 и запись теперь идет в table1. Делает SELECT * FROM table0, а потом просто TRUNCATE table0. Затем обработчик выставляет переменную в 0 и обрабатывает все в table1. Вы избавлены вообще от операции DELETE.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson