MySQL очень медленный на очень простых запросах SELECT


10

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

Например, у меня есть очень простая таблица с адресами:

CREATE TABLE `addresses` (
  `address_id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(64) CHARACTER SET latin1 NOT NULL,
  `firstname` varchar(64) CHARACTER SET latin1 NOT NULL,
  `street` varchar(64) CHARACTER SET latin1 NOT NULL,
  `housenumber` varchar(16) CHARACTER SET latin1 NOT NULL,
  `zip` varchar(5) CHARACTER SET latin1 NOT NULL,
  `city` varchar(64) CHARACTER SET latin1 NOT NULL,
  `email` varchar(64) CHARACTER SET latin1 NOT NULL,
  `phone` varchar(16) CHARACTER SET latin1 NOT NULL,
  `birthdate` date NOT NULL,
  PRIMARY KEY (`address_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

Эта таблица содержит около 800 записей, что на самом деле не так много. Но выполнение запроса

SELECT * FROM addresses

в тестовых целях, кажется, никогда не закончить. Я проверил это с помощью CLI mysql на самом сервере: он выводит некоторые строки таблицы, а затем очень долго ждет, пока не выведет следующие строки.

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

ВМ имеет 2 ГБ оперативной памяти и используется только 320 МБ. Процессор также работает на очень низком уровне от 1 до 2%. mytop не показывает никаких других запросов, которые блокируют сервер. ИТ-администратор сказал, что они ничего не изменили в аппаратной части.

Я уже пробовал что-то вроде перезапуска сервера базы данных, перезапуска виртуальной машины. Ничего не помогло

редактировать:

EXPLAIN SELECT * FROM addresses

дает мне этот результат:

+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
| id | select_type | table     | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | addresses | ALL  | NULL          | NULL | NULL    | NULL |  793 |       |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)

Виртуальная коробка, Xen или что-то еще? Как настроен диск хоста? есть ли другие виртуальные машины на том же компьютере, которые работают медленно? Ответ на эти вопросы может раскрыть ответ
— Мэтт

Я не владелец гипервизора, поэтому я не могу ответить на этот вопрос. Я уже спросил администратора гипервизора, знают ли они о каких-либо недавних изменениях, но он сказал нет.
— Табб

если можете, выключите mysql и запустите тест производительности диска и памяти. Не должно быть сложным. Идея состоит в том, чтобы просто изолировать, если это проблема с MySQL, возможно, проблема индекса, как указано в ответе ниже, или более распространенная.
— Мэтт

Хороший вопрос, я испытал это, вероятно, не будучи проблемой mysql. Запуск mysql -u username -ppassword mydb -e 'SELECT * FROM addressesвыводится медленно, но, добавляя `> test.txt`, он работает очень быстро. Теперь это, наверное, другой вопрос !? Как я мог расследовать это?
— Табб

Свяжитесь с владельцем гипервизора и попросите его проверить журналы на наличие ошибок. Конкретно дисковые ошибки. Скажите ему ваши симптомы. Резервное копирование сейчас.
— Мэтт

Ответы:


13

Если загрузка процессора низкая, это указывает на отсутствие проблем с отсутствующими индексами, если бы это было так, запросу просто потребовалось бы больше процессора и доступа к диску. Также вы сказали, что он работал в течение 3 лет.

Проверяли ли вы общую скорость доступа к диску (особенно в разделе, где расположена база данных)? Например, используя dd как здесь . То, что вы описываете, звучит как мертвый диск или полумертвый рейд. Надеюсь, у меня есть резервные копии?


Неплохо подмечено. Это может быть что-то простое, например, ошибка диска на хосте.
— Мэтт

9

Вы можете попробовать пару вещей,

  1. У вас есть настройки индексов?

Индексирование позволяет быстро находить записи без предварительного полного сканирования таблицы, значительно сокращая время выполнения.

CREATE INDEX idx_name ON addresses(name);
  1. Перед выполнением запроса сначала используйте ключевое слово EXPLAIN,

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

  1. Внесите некоторые изменения в свой mysql.ini, если его виртуальная машина увеличит объем оперативной памяти, и настройте свой mysql.ini, чтобы увидеть, увеличивается ли производительность.

Существует множество оптимизаторов MySQL, которые могут вам помочь.

Помогите это поможет


Хорошо, но создание индекса для довольно маленькой таблицы (<800 строк) не так полезно, как мне бы того хотелось. Завершение запроса, указанного выше, занимает более минуты. Полное сканирование такого маленького стола не займет так много времени.
— Табб

Итак ... вы добавили индексы? Если вы не уверены, в чем проблема, я начну с базового и продолжу свой путь вниз. Добавление индексов только увеличит производительность, если все сделано правильно.
— Энтони Форнито

Да, я добавил индекс в столбце имени. Но мой вышеупомянутый запрос даже не имеет ограничивающего предложения WHERE, поэтому ему придется прочитать всю таблицу и распечатать ее. Добавленный индекс не помог.
— Табб

Я добавил результат запроса EXPLAIN выше. Это выглядит хорошо для меня, но производительность все еще очень низка. Я не могу увеличить оперативную память, так как я не являюсь администратором менеджера виртуализации. Но htopпоказывает, что из 2050 МБ ОЗУ используется только 307 МБ.
— Табб

Об индексах вам действительно нужно подумать о том, какие столбцы индексировать, вы не хотите просто индексировать все, индексировать столбцы с наибольшим количеством, я делаю некоторые дикие предположения по этому поводу, но я бы начал с name«firstname». Во-вторых, вы уверены, что правильно сделали индексацию? возможные_ключи: NULL, если столбец равен NULL, это означает, что не найдено соответствующих индексов.
— Энтони Форнито
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.