MySQL запрос таблицы медленных запросов по первичному ключу - PullRequest
4 голосов
/ 02 июня 2011

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

id bigint первичный ключ медиаблок данных измененная отметка времени

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

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

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

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

Редактировать: По запросу объясните вывод:

+----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+
| 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

Ответы [ 4 ]

6 голосов
/ 02 июня 2011

Есть две проблемы, которые я вижу здесь изначально. Во-первых, у вас есть запрос с типом данных 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, я подумал о другой вещи, на которую вы должны обратить внимание (опять же, не убийца запросов, но это еще один удар по производительности). Если для вашего поля идентификатора не используется экономическое обоснование, выберите вместо него int. Int позволит 2,1 миллиарда строк, поэтому у вас не должно заканчиваться чисел. Установка этого параметра сэкономит ваше дисковое пространство и улучшит производительность запросов. Вот статья об этом:

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

0 голосов
/ 02 июня 2011

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

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

    • это после нового запуска БД? тогда это может быть просто временная проблема - запросы попадают в холодный кеш
    • это при дампе / загрузке БД? - затем измените ваши политики резервного копирования - используйте, например, репликацию или добавьте больше дискового ввода-вывода (добавьте больше дисков в RAID, измените диски на SSD, переразбейте свою систему на несколько дисков и т. д.)
    • это в пиковые времена чтения / записи? здесь также может помочь репликация - записать в master и сбалансировать нагрузку чтения между master и slave
  • Кроме того, действительно ли нужен этот медиумблоб?
0 голосов
/ 02 июня 2011

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

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

0 голосов
/ 02 июня 2011

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

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

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

...