MySQL высокая производительность для большого количества SELECTs / INSERTs / UPDATEs / DELETEs

9

Я создаю модуль, в котором каждый пользователь часто помещает запись в таблицу на 10–300 секунд.

Когда время истекает, запись удаляется. Дело в том, что будет много пользователей, и записи будут меняться очень часто - как это повлияет на производительность приложения для этой таблицы, потому что записи будут часто меняться, и мне интересно, хорошо ли с этим mysql? Подобно тому, как индексы приходят и уходят, данные изменяются примерно 200 раз в секунду для данной таблицы. Может быть, я выбираю плохое решение для такой работы. Какие-либо предложения ?

Спасибо!

Aivaras
источник
2
Вы пытались сохранить данные в memcache, а затем очищать их за одну транзакцию каждые несколько секунд?
3
«данные меняются, например, 200 раз в секунду для этой конкретной таблицы». Я думаю, что строка с указанием того, что эти данные должны храниться в памяти, время, в течение которого они должны сохраняться, ничтожно, поэтому, вероятно, не должно попадать на диск?
Индексы приходят и уходят? Я не могу придумать причину, по которой вам нужно создавать и удалять индексы очень часто.
Барри Браун

Ответы:

3

Одна вещь, которая должна быть принята во внимание, - то, как MySQL использует буферы для своих главных механизмов хранения: InnoDB и MyISAM .

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

InnoDB кэширует как данные, так и страницы индекса. Они загружаются в пул буферов InnoDB, размер которого определяется значением innodb_buffer_pool_size .

MyISAM кэширует только индексные страницы, и они загружаются в Key Cache (Key Buffer), размер которого равен key_buffer_size .

Вы должны использовать information_schema.tables для получения данных и размеров индексов, занимаемых на диске, чтобы правильно определить размер пула буферов InnoDB и кэш-памяти ключей MyISAM .

В зависимости от того, сколько у вас есть данных и сколько времени у вас будет, вы можете согреть кеширование следующим образом:

Для каждого стола TableT

  • перейти к каждому индексу NDX
  • для каждого индекса NDX
    • Запустите SELECT каждый столбец в NDX, по крайней мере, один столбец не проиндексирован в TableT из TableT

Этим вы гарантируете, что каждая страница данных и индекса будет прочитана хотя бы один раз. Они будут сидеть в тайнике. Эта концепция частично и в принципе практикуется компанией Percona . Percona встроила эту концепцию в mk-slave-prefetch . Что делает эта программа

  • читать журналы ретрансляции на подчиненном устройстве, перед тем как подчиненное устройство обрабатывает в нем SQL
  • взять оператор SQL из журнала ретрансляции и преобразовать его в SELECT, используя предложения WHERE, GROUP BY и ORDER BY в качестве руководства по выбору индексов
  • выполнить оператор SELECT, полученный из преобразованного SQL

Это заставляет подчиненное устройство иметь 99,99% данных, необходимых ведомому для быстрой обработки SQL. Это также приводит к тому, что ведомое устройство готовится в случае, если вы вручную переключаетесь на ведомое устройство и переводите его в ведущий, ЧТО КЭШЫ ПРОСТО ТОЛЬКО ОДНОВРЕМЕННО, КАК МАСТЕР, КОТОРЫЙ ВЫ НЕ СДЕЛАЛИ.

ВЫВОД

Ничто не сравнится с готовностью, желанием и способностью использования кэшей в среде с тяжелыми INSERTS, UPDATE и DELETE.

Попробуйте!

ПРЕДОСТЕРЕЖЕНИЕ

С появлением таких продуктов, как memcached, некоторые избавились от необходимости выполнять правильную настройку MySQL. Конечно, многие сайты извлекают выгоду из ускорения поиска данных, обеспечиваемого путем контроля поведения кэширования данных, что разработчики быстро заметили с помощью memcached. Многие другие сайты, просто переключая хранилища или правильно настраивая MySQL, получили те же преимущества в производительности. Прежде чем отказаться от базы данных и строго использовать ее в качестве хранилища, максимально используйте свою базу данных. Следуйте правилам due diligence, и вы можете быть приятно удивлены тем, что MySQL сделает для вас.

RolandoMySQLDBA
источник
5

Если это плохое решение будет зависеть от многих вещей. Должны ли эти данные быть постоянными? В противном случае, возможно, решение, которое просто хранит эти данные в памяти, будет работать лучше.

«Многие пользователи» никому не помогают. MySQL, скорее всего, будет в порядке, если «много» будет означать несколько сотен. (Хотя в зависимости от того, с чем еще должна справиться ваша база данных. Скорее всего, несколько тысяч также должны работать.)

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

Но без фактических цифр и некоторой информации об оборудовании, используемом вашим сервером баз данных, на этот вопрос невозможно ответить с большой точностью.

Лучше всего было бы написать какое-нибудь небольшое приложение, которое просто имитирует объем нагрузки, который, как вы думаете, вы получите, не выполняя много реальной обработки, просто отбрасывает множество записей на сервер, удаляет их, с той же скоростью запускает некоторые запросы, такие как Остальная часть вашей программы будет генерировать. Посмотрите на свой сервер и посмотрите, не влияет ли это каким-либо образом.

Не уверен, но для MySQL есть опции, которые позволят ему полностью кэшировать таблицу в памяти. В любом случае это происходит во многих ситуациях, и, скорее всего, вам не придется много менять. Но если вы говорите об очень большом количестве пользователей и записей, вы можете настроить несколько параметров, чтобы оптимизировать кэширование для ваших особых потребностей.

Торстен Мюллер
источник
4
+1 за предложение решения, которое хранит данные в памяти.
3

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

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

Значение ключа 1123234441 для активных строк, а значение ключа: 9123234441 для неактивных строк (первая цифра в этом примере используется следующим образом: 1 = активный, 9 = неактивный).

Теперь, когда пользователь удаляет строку, вы физически не удаляете строку, вы обновляете ключ (Ой!), Это автоматически перемещает строку в раздел неактивных строк.

Конечно, вам нужно ограничить свои выборки для чтения данных только из активного раздела. Самое интересное, что удаление раздела неактивных строк происходит очень быстро.

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

Чтобы расширить выбор, используйте правильное индексирование и улучшите вставки, чтобы минимизировать размер строки и количество индексов (это утверждение очень общее ...)

Для справки см .: http://dev.mysql.com/doc/refman/5.1/en/partitioning-types.html Надеюсь, это поможет.

Без шансов
источник
2
Я не уверен, имеет ли это смысл для этой конкретной проблемы (я все еще думаю, что mysql будет кэшировать все это, и, скорее всего, эти записи не увидят диск). Но +1 за указание на интересную технику оптимизации, которую я до сих пор не знал.