2015-11-24 1 views
3

У меня есть база данных с одной таблицей, которая отслеживает состояние пользователя. Когда я закончил обработку строки, ее больше не нужно хранить в базе данных и ее можно удалить.Увеличение производительности запроса от удаления строк в базе данных SQL?

Теперь можно сказать, что я хотел отслеживать строку вместо ее удаления (для исторических целей, аналитики и т. Д.). Было бы лучше:

  1. Оставьте данные в одной таблице и отметьте строку, как «использовать» (с дополнительным столбцом или что-то подобное)

  2. Удалить строку из таблицы и вставьте его в отдельную таблицу, которая создается только для исторических целей

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

Для выбора № 2 интересно, будет ли постоянное удаление строк в конечном итоге вызвать такие проблемы, как фрагментация?

+0

Ах, это для mysql. Не следует отмечать оба. – jnortey

+0

Для выбора # 2 - вместо удаления строк после их переноса в другую таблицу - не могли бы вы их повторно использовать. Отметьте строку как более не используемую и найдите ее, когда вам нужно отслеживать текущее состояние и использовать сначала найденное - если ни один не добавляет дополнительную запись. Таким образом, вы избегаете фрагментации. Не сказать, что это хорошее решение - просто способ избежать фрагментации, если вы спуститесь по этому маршруту. – PaulF

+0

Спасибо за предложение PaulF, однако я бы хотел избежать дублирования данных, если это возможно. – jnortey

ответ

3

производительности запроса будет лучше в долгосрочной перспективе:

Что происходит с вечно вставляет:

таблица растет, индексы растут, показатели индекса (поиск) является уменьшается от размера стол, особенно вставка производительности.

Что происходит со стиранием:

Таблица страниц фрагментировались, поэтому удаленные пространство повторно не используется на 100%, как и ожидалось, более около 50% в MySQL. Таким образом, таблица по-прежнему растет примерно вдвое больше, чем вы могли бы ожидать за свой объем данных. Индекс становится фрагментированным и становится односторонним: он содержит ваши новые данные, а также структуру для ваших старых данных. Это зависит от структуры ваших данных о том, насколько это плохо. Однако эта ситуация стабилизируется при определенной производительности. Эта точка производительности имеет 2 преимущество:

1) В таблице более ограничена по размеру, поэтому потенциальные сканы полного стола являются быстрее

2) Быстродействие предсказуемо.

Из-за фрагментации, однако, эта точка производительности не равна примерно вдвое большему количеству данных, она, как правило, немного хуже (сравнивайте ее, чтобы увидеть себя). Преимущество сценария удаления, однако, поскольку у вас есть меньший набор данных, вы можете восстановить свой индекс раз в каждый разумный период, тем самым повысив свою производительность.

Альтернативы

Есть две альтернативы вы можете посмотреть на то, чтобы улучшить производительность:

  • Переключитесь MariaDB: Это прирост производительности около 8% на больших наборах данных (мое наблюдение, набор данных сжатые данные около 200 ГБ)

  • Посмотрите на разбиение на разделы: если у вас есть удобный параметр разбиения на разделы, вы можете создайте для вас серию «маленьких таблиц» и запретите логику для удаления, восстановления и управления историческими данными. Это может дать вам лучший профиль производительности.

+0

Я больше беспокоюсь о производительности запросов, чем о пространстве. Если пространство не является проблемой, скажете ли вы, что вариант №2 является лучшим вариантом? Если я правильно читаю, результат выполнения запроса не так плох с опцией 2. – jnortey

+0

Я бы использовал постоянное удаление или разбиение. Как структурируются ваши данные? Первичный ключ и т. Д. (Обновите свой вопрос и отправьте сообщение, затем я рассмотрю этот сценарий). –

1

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

Если вы удаляете записи исключительно по возрасту, то PARTITION BY RANGE(TO_DAYS(...)) - отличный способ построить таблицу. DROP TABLE мгновенно и ALTER TABLE ... REORGANIZE ... для создания новой недели (или месяца или ...) также мгновенно. См. my blog.

Если вы «переместите» записи в другую таблицу, таблица не будет очень быстро сокращаться из-за фрагментации. Если у вас достаточно места на диске, это не ошибка. Если в некоторых запросах необходимо увидеть как текущие, так и архивные записи, используйте UNION ALL; это довольно легко и эффективно.