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

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

То, можливо, це проблема у фазі надсилання даних, але я не впевнений.

VM має 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 чи щось інше? Як налаштований хост-диск? Чи є інші VM в тій же коробці, що працює також повільно? Відповідь на ці запитання може виявити відповідь
Метт

Я не є власником гіпервізора, тому реально не можу відповісти на це. Я вже запитав адміністратора гіпервізора, чи знають вони про якісь останні зміни, але він відповів "ні".
вкладка

якщо можете, вимкніть 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, якщо її VM збільшить оперативну пам’ять і налаштуйте ваш mysql.ini, щоб побачити, чи збільшується продуктивність.

Існує багато оптимізаторів MySQL, які можуть вас направити.

Допомога це допомагає


Гаразд, але створення індексу на зовсім невеликій таблиці (<800 рядків) здається не настільки корисним, як мені потрібно. На завершення запиту, цитованого вище, потрібно більше хвилини. Повне сканування такої невеликої таблиці не повинно зайняти так довго.
вкладка

Отже ... ви додали індекси? Якщо ви не впевнені, у чому полягає проблема, я б почав базуватись і працювати вниз. Додавання індексів підвищить продуктивність лише при правильному виконанні.
Ентоні Форніто

Так, я додав індекс у стовпчик імен. Але мій вище запит навіть не має обмежувального пункту WHERE, тому доведеться прочитати всю таблицю та роздрукувати її. Доданий індекс не допоміг.
вкладка

Я додав результат запиту EXPLAIN вище. Це мені добре виглядає, але продуктивність все ще дуже низька. Я не можу збільшити оперативну пам’ять, оскільки я не адміністратор менеджера віртуалізації. Але htopвидно, що з 2050 МБ оперативної пам’яті використовується лише 307 МБ.
вкладка

Про індекси вам дійсно потрібно думати про те, які стовпці потрібно індексувати, ви не хочете просто індексувати все, індексувати ті, у яких найбільша кількість, я роблю деякі дикі припущення щодо цього, але я б почав з name«ім’я». По-друге, ви впевнені, що зробили індексацію правильно? possible_keys: NULL, якщо стовпець NULL, це вказує, що не вдалося знайти відповідних індексів.
Ентоні Форніто
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.