SQLinfo.ru - Все о MySQL

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

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

Вы не зашли.

#1 03.04.2009 23:10:40

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Сильные проблемы с удалением из больших таблиц

Есть таблицы, порядка миллиона записей. Стоит задача периодически удалять записи старше определенного периода (обычно это сутки). 

Вот одна из них.

CREATE TABLE `brevno_ext_access` (
  `id` bigint(20) unsigned NOT NULL auto_increment,
  `siteid` int(10) unsigned NOT NULL,
  `sessionid` bigint(20) unsigned NOT NULL,
  `ipnum` int(10) unsigned default NULL,
  `pageid` int(10) unsigned NOT NULL,
  `GET` mediumtext,
  `DATE` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  PRIMARY KEY  (`id`),
  KEY `pageid` (`pageid`,`DATE`),
  KEY `sessionid` (`sessionid`,`DATE`),
  KEY `siteid` (`siteid`,`DATE`),
  KEY `ipnum` (`ipnum`),
  KEY `DATE` (`DATE`)
) ENGINE=InnoDB AUTO_INCREMENT=6888171 DEFAULT CHARSET=latin1

В условиях отсутствия посторонней нагрузки на таблицу запрос на удаление вида

DELETE FROM brevno_ext_access WHERE DATE < '2009-04-02 23:40:12';


выполняется порядка 140 cекунд (удалению подвергаются где-то 100k записей из 1,5-2 миллионов)

В то же время в тех же условиях, например, запрос

SELECT * FROM brevno_ext_access WHERE DATE < '2009-04-02 23:40:12';


проходит за 0.63 сек. Если выбирать не *, а id, то вообще выполняется 0.12 сек.

Пробовали через временную таблицу выбрать сначала нужные id, потом удалить через JOIN. Примерно то же самое.
А в рабочей обстановке ситуация усугубляется тем, что в таблицу идет пара десятков INSERT'ов в секунду.

Из-за чего так медленно? Может, ключей много? (сильно ли могут лишние ключи влиять?)

Как бы эту ситуацию улучшить?


Кстати. Про статус updating. В руководстве по MySQL это состояние находится, во-первых, среди т.н. Delayed insert thread states.
http://dev.mysql.com/doc/refman/5.0/en/ … tates.html

Во-первых, откуда слово delayed? Во-вторых, в руководстве про этот статус ничего не написано. Кто-нть знает что-нибудь интересное про этот статус? 

Сервер 5.0.75-log() на FreeBSD 7.1

Неактивен

 

#2 04.04.2009 00:24:47

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

Re: Сильные проблемы с удалением из больших таблиц

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

Неактивен

 

#3 04.04.2009 01:07:42

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Сильные проблемы с удалением из больших таблиц

Т.е. узкое место - именно в модификации таблицы, а не в выборке нужных записей?

потом удалять по 1000 штук.

Т.е. удалить 1 раз 100 000 - это хуже, чем 100 раз по 1000, причем сразу один за другим?

Система не сказать, что в очень подвешенном состоянии. Нагрузка не оч. большая, таблица не лочится, т.к. InnoDB. Нужно не только, чтобы система не загружалась, но и чтобы было быстрее. Если время удаления не уменьшится, то смысла мало.

Неактивен

 

#4 04.04.2009 01:30:15

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

Re: Сильные проблемы с удалением из больших таблиц

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

Неактивен

 

#5 04.04.2009 02:48:22

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Сильные проблемы с удалением из больших таблиц

Вообще предполагалось, что это нужно раз в пять минут (при пятиминутных интервалах удаления требуется где-то десять секунд).

Можно немного поподробнее про 1000 строк: как это разбиение вообще реализовывается? там между этими тысячами интервал ожидания поставить или просто если будут отдельные запросы, то само собой получится?

Лочится вряд ли, т.к. в нее инсерты идут и не написано Locked, написано update.

(кстати; за сутки уже придется не 100 000 строк удалять, а два миллиона).

Неактивен

 

#6 04.04.2009 10:56:32

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Сильные проблемы с удалением из больших таблиц

Я немножко вмешаюсь smile

1. Можно удалять и балком — к старым записям обращения нету в штатном режиме, поэтому
блокировки не заметны: они ставятся как раз между удаляемыми записями.
2. Удалять логичнее по id (благо, он автоинкрементальный): найти последний удаляемый
по ключу и удалить по primary ключу — чуть-чуть быстрее (блокировки не будут ставиться
на второй ключ).
3. Для логов это, наверное, не самый лучший способ хранения. Традиционно используют
исамовские таблички и «перемещающийся» MERGE/VIEW над ними. Тогда «удаление старых» —
это чрезвычайно быстрая операция.

UPD: Кстати, если заапгрейдиться до 5.1, то при уже работающей схеме чрезвычайно увеличит
скорость добавлений-удалений партишны линейные над датой. По сути — третий пункт, но
несколько завуалированный для пользователя. Даже в случае удаления с WHERE — индекс
будет перестраиваться не на всех записях, а только на нужных разделах. Менее глубокий
индекс => меньше перестраивать => быстрее работает.

Неактивен

 

#7 04.04.2009 16:25:10

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Сильные проблемы с удалением из больших таблиц

Подобные вмешательства только приветствуются smile

Дело, видимо, не в блокировках - при отсутствии активности по отношению к таблице то же самое получалось.

По id оказалось, к сожалению, так же медленно sad

Как же можно использовать для логов MyISAM? Не возникает ли проблем от того, что лочится вся таблица при записи?

партишны линейные над датой. По сути — третий пункт, но
несколько завуалированный для пользователя. Даже в случае удаления с WHERE — индекс
будет перестраиваться не на всех записях, а только на нужных разделах. Менее глубокий
индекс => меньше перестраивать => быстрее работает.

к сожалению, настолько высокий полет мысли, что я почти ничего не понял smile
можно еще раз, почему 5.1 делает менее глубокий индекс, и что такое линейный partition над датой? (я извиняюсь за свою темноту)

Неактивен

 

#8 06.04.2009 14:47:23

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Сильные проблемы с удалением из больших таблиц

Наверное, я просто плохо выразился smile

Я имел в виду вот такого зверя:

CREATE TABLE log (id INT KEY AUTO_INCREMENT, ts TIMESTAMP, ...)
PARTITION BY RANGE (ts) (
  PARTITION p2009_01 VALUES LESS THAN ('2009-02-01'),
  ...
  PARTITION p2009_12 VALUES LESS THAN ('2010-01-01')
)


Реально это будет 12 табличек с одним именем. Индекс будет проще, т.к. значений в
индексе меньше (в месяце меньше строк, чем во всей таблице).

Неактивен

 

#9 08.04.2009 02:15:07

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Сильные проблемы с удалением из больших таблиц

Ух ты, интересно! smile

Правда, есть ряд проблем:

1. Пока в руководстве написано, что на датой такое можно делать только по дням или годам:

http://dev.mysql.com/doc/refman/5.1/en/ … uning.html

This type of optimization can be applied whenever the partitioning expression consists of an equality or a range which can be reduced to a set of equalities, or when the partitioning expression represents an increasing or decreasing relationship. Pruning can also be applied for tables partitioned on a DATE or DATETIME column when the partitioning expression uses the YEAR() or TO_DAYS() function.

Pruning can be used only on integer columns of tables partitioned by HASH or KEY. For example, this query on table t4 cannot use pruning because dob is a DATE column:

SELECT * FROM t4 WHERE dob >= '2001-04-14' AND dob <= '2005-10-15';

А у нас там таблица всего за сутки...


2. Допустим, такое можно было бы сделать. Тогда встала бы проблема, что разделение слишком быстро устаревает (за сутки данные полностью обновляются). Что делать в случае, когда устаревает разделение? (или просто хочется его переделать)
Это ж он будет заново всю таблицу перестраивать? Если часто так делать, то затраты на это дело могут перекрыть выигрыш...

3. Кстати, каково вменяемое количество частей? Например, таблицу за сутки разбить по минутам - это нормально или уже слишком?

Какие вообще примерно ресурсы требуются для этого? (я имею в виду, при одинаковых данных какие служебные ресурсы задействуются?)

Неактивен

 

#10 08.04.2009 13:22:16

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Сильные проблемы с удалением из больших таблиц

Хм, жуткая особенность smile

Насколько я помню, под RANGE можно вставить любую функцию, в том числе и UNIXTIME.
PRUNING над целыми числами работает нормально.

Физически каждый раздел = отдельная таблица. Исходи их этих соображений.

Неактивен

 

Board footer

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