MySql - медленная фаза отправки данных - PullRequest
29 голосов
/ 14 мая 2009

Один из моих запросов на MySQL 5.0.45 работает медленно в фазе «отправки данных». Запрос является простым выбором, возвращает около 300 полей целочисленных идентификаторов в качестве набора результатов.

mysql> SELECT source_id FROM directions WHERE (destination_id = 10);
+-----------+
| source_id |
+-----------+
|         2 |
|         8 |
...
|      2563 |
+-----------+
341 rows in set (2.13 sec)

Я точно уверен, почему фаза «отправки данных» такая медленная и что можно сделать, чтобы сделать ее быстрой. Обратите внимание, что я выполняю этот запрос по приглашению MySQL на самом сервере, поэтому не ожидаю, что он потратит так много времени на «отправку данных». Любые подсказки?

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

Этот запрос выполняется тысячи раз в день, и он не может тратить на него 2 секунды каждый раз.

Результат профилирования:

mysql> show profile for query 4;
+--------------------------------+----------+
| Status                         | Duration |
+--------------------------------+----------+
| (initialization)               | 0.000003 |
| checking query cache for query | 0.000051 |
| checking permissions           | 0.000007 |
| Opening tables                 | 0.000011 |
| System lock                    | 0.000005 |
| Table lock                     | 0.000023 |
| init                           | 0.00002  |
| optimizing                     | 0.00001  |
| statistics                     | 0.00006  |
| preparing                      | 0.000014 |
| executing                      | 0.000005 |
| Sending data                   | 2.127019 |
| end                            | 0.000015 |
| query end                      | 0.000004 |
| storing result in query cache  | 0.000039 |
| freeing items                  | 0.000011 |
| closing tables                 | 0.000007 |
| logging slow query             | 0.000047 |
+--------------------------------+----------+
18 rows in set (0.00 sec)

ОБНОВЛЕНИЕ: я наткнулся на следующий URL, который говорит

Each time means the time elapsed between the previous event and the new event. So, the line:
| Sending data | 0.00016800 |
means that 0.00016800 seconds elapsed between "executing" and "Sending data". It is, it takes 0.00016800 seconds to execute the query.

http://forums.mysql.com/read.php?24,241461,242012#msg-242012

Может кто-нибудь подтвердить?

Ответы [ 6 ]

19 голосов
/ 14 мая 2009

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

DESCRIBE SELECT source_id FROM directions WHERE (destination_id = 10);

Это покажет вам таблицу с перечислением шагов, необходимых для выполнения вашего запроса. Если вы видите большое значение в столбце 'lines' и NULL в столбце 'key', это указывает на то, что ваш запрос должен сканировать большое количество строк, чтобы определить, какие из них следует вернуть.

В этом случае добавление индекса для destination_id должно значительно ускорить ваш запрос, с некоторой стоимостью для вставки и удаления скорости (так как индекс также необходимо будет обновить).

6 голосов
/ 12 декабря 2017

У меня была такая же проблема: Отправка данных была очень медленной, но у меня были правильные индексы и т. Д.

После долгих поисков я обнаружил, что мой join сравнивал два поля, которые были проиндексированы, но имели разные параметры сортировки - одно было latin1_swedish_ci, а другое - uft8_general_ci.

Как только я отправил их обоих на utf8, запрос был значительно быстрее (с 2,7 секунды до 0,002 секунды)

6 голосов
/ 09 декабря 2015

Возможно, вы могли бы взглянуть на аппаратную часть сервера MySQL. Как Mysql doc говорит:

Отправка данных

Поток считывает и обрабатывает строки для оператора SELECT и отправляет данные клиенту. Поскольку операции, происходящие во время этого состояния, имеют тенденцию выполнять большие объемы доступа к диску (чтения), это часто является наиболее длительным состоянием в течение времени жизни данного запроса.

Итак, если ваш сервер имеет медленный дисковый ввод-вывод из-за огромного файла базы данных / таблицы таблиц или отключенного параметра табличного файла InnoDB / фрагментации / неправильно настроенного RAID / запускается процесс сбоя диска (ожидание скорой смерти диска) / любой другой причине диска Медлительность ввода / вывода - это может быть причиной резко увеличенного шага "Отправка данных", так как на этом этапе сервер собирает все запрошенные данные с диска и отправляет их клиенту.

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

1 голос
/ 14 мая 2009

У вас есть индексы в этой таблице? Вы сказали, что он возвращает около 300. Но сколько нужно найти, чтобы найти эти 300?

0 голосов
/ 25 мая 2018

Я испытал это после перехода с MySQL 5.5.x на 5.7.x. Мой запрос с использованием объединений был быстрым на MySQL 5.5 и очень медленным на MySQL 5.7.

Проблема заключалась в том, что MySQL 5.7 выбрал другой набор индексов, чем MySQL 5.5.

Добавление USE INDEX устранило проблему.

0 голосов
/ 14 сентября 2010

Ваш запрос тратит 2.127019 на выполнение запроса. Вероятно, это связано с тем, что у вас большой объем данных, а у вас отсутствует индекс в столбце destination_id. Попробуйте:

CREATE INDEX index_destination_id ON направления (destination_id);

Тогда ваш запрос будет работать гладко.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...