Как оптимизировать выборку из БД с большим количеством insert/update?
Понимаю, что архитектура не очень хорошо была продумана, но сейчас переделать возможности нет, нужно исправлять.
Ситуация такая. В БД идет запись insert/update с достаточно большой частотой. в минуту точно несколько записей, а то и десятков. Но и получать данные нужно часто и быстро. Несколько раз в секунду.
Я так понимаю, что при вставке и обновлении, перестраиваются индексы, это занимает много времени. Избавиться от них совсем тоже плохой вариант - выборка будет идти долго. Но и сейчас select заапросы значительно тормозят. Как добиться оптимизации?
Это не очень большая нагрузка, я бы сказал даже никакая. Штатный режим. Расставьте индексы и работайте как обычно. пока в базе не будет десятка миллионов записей должно работать шустро. От структуры конечно зависит но в общем случае будет так.
ок, плоская таблица с селектом по индексам(индексы видимо не составные, а на каждое поле), експлэйн показывает использование индексов(да?), каково время запроса, сколько строк выборка, какой ордер, лимит? Если не сложно пример запроса.
select odds from `m8omf_test_odds` where `match` = 'test' and market_id = 10 and active = 1 and outcome_id = 10 and product = 1 order by id desc limit 1
Вот EXPLAIN
SIMPLE
type: index_merge
possible_keys: match,active,product,market_id,m8omf_test_odds_unique_idx
Key: match,market_id
key_len: 82,4
rows:22
Extra: Using intersect(match,market_id); Using where;
Индексы: match, match_id, market_id, outcome_id, product.
И есть индекс по product, market_id, outcome_id, active, match
в смысле? майадмин отдал-забрал, засек время чисто на запрос, там циферка есть - время запроса, за какое время зарос выполнился, работа майадмина по формированию запроса и вывода результатов из этого времени вычтены. Секунды это реально много для выборки по индексированным полям, разве что машина слабенькая и памяти под мускуль мало.
- Я бы попробовал все же для начала из поиска удалять по 1 полю, найти самое тормозное(есть подозрение что притормаживает какой-то конкретный индекс).
- При тормозах индекса можно попробовать удалить и пересоздать.
- если есть время и возможность поэксперименитировать - поменять тип таблицы(тоже не указан).
- Как вариант - разбить на подзапросы, используя in( select some_id from some_table where условие), таким образом явно указав движку какие ключи выбрать первыми. Это в последнюю очередь, обычно движок старается сам подобрать порядок построения более оптимальный, обычно это работает хорошо без вмешательств.
- попробуйте вариант без ордера, есть подозрение что в нем может быть засада.
PS: всегда создавать бэкап перед эксперименитами.
Я правильно понял, что у вас два индекса на таблице по пять полей каждый, но в выборке вы используете комбинацию полей, отличную от тех, что в индексах?
Я бы разделил эти индексы как-то более вменяемо (если этот ваш запрос является критичным и часто используемым).