2011-06-02 2 views
4

Итак, у меня есть таблица, которая используется в основном как установка NoSQL. Структура:MySQL медленная таблица запросов на первичный ключ

ID BIGINT первичный ключ MEDIUMBLOB данные модифицированная метка времени

Она насчитывает около 350k строк. Запросы, которые выполняются на нем, структурированы следующим образом:

выберите данные из таблицы, где id = XXX;

Настольный двигатель InnoDB. Я замечаю, что иногда запросы против этой таблицы довольно медленные. Иногда им требуется 3 секунды. Таблица составляет 3 ГБ на диске, и я дал innodb_buffer_pool_size 4G.

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

Edit: В соответствии с просьбой объяснить вывод:

+----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref | rows | Extra | 
+----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+ 
| 1 | SIMPLE  | cache | const | PRIMARY  | PRIMARY | 8  | const | 1 |  | 
+----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+ 

создать таблицу:

CREATE TABLE `cache` (
    `id` bigint(20) unsigned NOT NULL DEFAULT '0', 
    `data` mediumblob, 
    `modified` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

ответ

6

Есть два вопроса, которые я вижу здесь изначально. Во-первых, у вас есть запрос с типом данных blob. Это приведет к проблемам с производительностью, когда дело доходит до получения данных. Во-вторых, вы используете InnoDB, который оптимизирован для записи. Это означает, что, хотя это, вероятно, лучший выбор в целом, в экстремальных ситуациях чтения он может быть менее результативным, чем MyISAM. Ни одна из этих проблем не является убийцами сделок, но каждый из них повышает производительность. Однако, помимо этого, я не уверен, что могу дать вам хороший ответ о том, что вы можете сделать, чтобы лучше оптимизировать, не предварительно сделав профилирование. Это то, что я бы рекомендовал вам сделать первым. Профилируйте свой запрос, чтобы выяснить, что такое план выполнения, а затем определить, почему план выполнения настолько медленный.

Вот хороший «Топ-10» список оптимизаций MySQL. По крайней мере, пара применяется в вашей ситуации непосредственно:

http://20bits.com/articles/10-tips-for-optimizing-mysql-queries-that-dont-suck/

Вот еще одна хорошая оптимизация статья, которая идет в настройках сервера, а также (для InnoDB специально):

http://www.mysqlperformanceblog.com/2007/11/01/innodb-performance-optimization-basics/

Основываясь на CREATE TABLE, который вы предоставили, я подумал о другой вещи, к которой вы должны обратиться (опять же, это не убийца запросов, а еще один удар производительности). Если нет бизнес-кейса для использования bigint для вашего поля ID, выберите вместо него int. Int будет содержать 2,1 миллиарда строк, поэтому вам не следует заканчивать номера. Создание этого переключателя позволит вам сэкономить место на диске и повысить производительность запросов. Вот статья о нем:

http://ronaldbradford.com/blog/bigint-v-int-is-there-a-big-deal-2008-07-18/

+2

InnoDB разве оптимизирован только для записи - хорошо спроектированный InnoDB таблицы с преимуществом это кластерный индекс будет превосходя любой другой двигатель http://stackoverflow.com/questions/4419499/mysql-nosql-help-me-to -choose-the-right-one-on-a/4421601 # 4421601 –

+0

Я не уверен, что согласен с InnoDB. У меня мои настройки довольно близки к тому, что предлагается по второй ссылке. – Jon

+0

Извините, мне кажется, я немного неясен. InnoDB лучше оптимизирован для записи по сравнению с MyISAM, который лучше оптимизирован для чтения. InnoDB, вероятно, ваш лучший выбор, я просто пытался сказать, что с точки зрения чтения это не лучший выбор. – IAmTimCorey

0

Не могли бы вы опубликовать CREATE TABLE заявление, а также выход EXPLAIN select data from table where id=XXX? Как io ждут в системе?

Моя лучшая догадка заключается в том, что вы привязаны к IO и потому, что строки не имеют одинакового размера, они должны искать данные. У вас достаточно памяти, чтобы она могла хранить кешированные данные. Эта ссылка описывает некоторые профилирования низкого уровня в MySQL, которые могут быть полезны.

http://dev.mysql.com/tech-resources/articles/using-new-query-profiler.html

+0

Я обновил вопрос, чтобы включить эту информацию. – Jon

0

Попробуйте использовать минимальный размер идентификатора, как это возможно. Если это числовой ключ, который, как вы знаете, никогда не будет больше, чем несколько миллионов, вы можете использовать MEDIUMINT UNSIGNED и сохранить себе байт для каждой записи по INT, что может немного ускорить поиск. Тем не менее, 3 ГБ - очень много всего за 350 000 строк.

Похоже, что вы также можете получить некоторый взмах для своего доллара, используя partitioning feature, чтобы разбить стол на логические единицы. Возможно, вы захотите в Google «mysql vertical partitioning», в частности; если есть большие столбцы, к которым вы часто не обращаетесь, было бы гораздо более эффективно перемещать их в отдельную таблицу и запрашивать ее только тогда, когда вам это нужно.

+0

Ну, вся идея здесь заключалась в том, чтобы сделать только один запрос для извлечения данных. Это просто оказалось намного медленнее, чем я надеялся. Не уверен, что размер int сделает для меня многое. – Jon

+0

Честно? Вероятно, нет, но это может сделать незначительное улучшение скорости вашего запроса. Я действительно думаю, что вертикальный раздел - это путь, так как кажется, что ваши строки относительно большие. К сожалению, MySQL не поддерживает вертикальное разделение изначально, поэтому вы вынуждены эмулировать его с помощью нескольких таблиц. Хотел бы я помочь. –

0

Вещи, которые я бы искать:

  • когда медленные запросы появляются?

    • Это после нового старта БД? то это может быть лишь временная проблема - запросы попадают в холодный кеш
    • это во время загрузки DB/загрузки? - затем измените свои политики резервного копирования - например, используйте репликацию или добавьте больше ввода-вывода на диск (добавьте больше дисков в RAID, замените диски на SSD, переформатируйте свою систему на нескольких дисках и т. д.)
    • это во время пикового чтения/записи? репликация также может помочь здесь - записать в основной и балансировочный баланс считывания между ведущими и ведомыми устройствами
  • Также - это тот, который необходим на самом деле?
+0

Они случаются спорадически в течение дня. БД на некоторое время. Мы не создаем резервные копии этих данных, так как это только кеш, который можно перестроить. Среднее значение blob * является * таблицей. Данные в нем - это целая цель иметь таблицу. – Jon

Смежные вопросы