Для своего сайта я использую PHP API для Flickr (http://www.flickr.com/services/api/). Этот API предоставляет несколько полезных методов для получения фотографий вокруг определенных позиций GPS.
Вызов методов API выглядит как URL с конкретными параметрами, такими как широта, долгота, ключ API, радиус, сортировка и т. Д. Скажем, это будет выглядеть как http://api.flickr.com/method?lat=0.0&lon=0.0&radius=10
Мой сайт делает более 200 000 вызовов API для создания нескольких страниц с изображениями из Flickr. Это очень сложный API, поэтому я создал кеш результатов в базе данных mySQL.
Упрощенная схема таблицы InnoDB с кешем:
char(32) request
datetime expires // 2-3 days
text response // serialized data from API response
где request
- это ПЕРВИЧНЫЙ КЛЮЧ, представляющий хэш MD5 URI запроса. Остальные поля довольно просты:)
Проблема возникает, когда таблица становится достаточно большой, например, более 100 000 строк. Новый INSERTs
занимает до 2 секунд (и до 6 (!) Секунд с 1 000 000 строк).
Насколько я понимаю, проблема в том, что PRIMARY INDEX и двигатель работают на InnoDB. Каждый раз, когда вставляется новый запрос, механизм InnoDB перестраивает индекс дерева и перемещает данные, потому что MD5 (запрос) является действительно случайным значением.
Итак ... Вопрос в том, есть ли лучший способ кешировать такие запросы? Или, может быть, мне стоит перейти на движок MyISAM? Или, может быть, я должен попробовать псевдоразделение и создать несколько таблиц для решения проблемы? Или можно просто использовать не BTREE, а индекс HASH?
Любые идеи приветствуются!
Edit:
Хорошо, я попытался изменить таблицу, как предложили Фурикан и Йохан, но все же не повезло - вставка занимает до 3 секунд. В настоящее время поле request
стало обычным неуникальным индексом, а новый столбец id
был добавлен как ПЕРВИЧНЫЙ КЛЮЧ с автоматическим приращением. Также я попытался добавить 4 раздела в эту таблицу с одинаковыми результатами.
Я думаю, что индекс для поля request
все еще является узким местом. Единственный способ, который я сейчас вижу, - это определить все возможные параметры, добавить их в виде столбцов в таблицу и затем создать для них индекс.
Есть еще идеи? :)
Редактировать 2:
Салман А в комментариях ниже сказал, что его аналогичная таблица работает намного лучше (~ 0,03 для вставки). Эта проблема может быть в IO нагрузки на систему. Хотя я не могу на него сильно нагрузить.
iostat
Результаты:
avg-cpu: %user %nice %system %iowait %steal %idle
22.94 0.71 8.42 8.50 0.00 59.43
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sda 38.01 151.04 114.32 1383655437 1047309046
iotop
Результаты:
Total DISK READ: 152.91 K/s | Total DISK WRITE: 197.67 K/s
С MySQL на вершине списка как для записи, так и для чтения. Может быть, мои диски почти мертвы? Как я могу проверить производительность дисков?