Как использовать EXPLAIN для * прогнозирования * производительности MySQL-запроса? - PullRequest
52 голосов
/ 25 апреля 2009

Я помогаю поддерживать программу, которая по сути является дружественным интерфейсом только для чтения, для большой и сложной базы данных MySQL - программа создает специальные SELECT-запросы из пользовательского ввода, отправляет запросы в БД, получает результаты, обрабатывает их и отображает их обратно пользователю.

Я бы хотел добавить некоторую форму разумного / эвристического прогноза для ожидаемой производительности построенного запроса - иногда пользователи непреднамеренно делают запросы, которые неизбежно будут занимать очень много времени (потому что они будут возвращать огромные наборы результатов, или потому что они "идут вразрез" с тем, как индексируется БД), и я хотел бы иметь возможность отображать пользователю некоторую "несколько надежную" информацию / предположение о том, сколько времени займет запрос. Он не должен быть идеальным, если только он не настолько плохо и часто не справляется с реальностью, что вызывает эффект «крик волка», когда пользователи учатся его игнорировать ;-) На основании этой информации пользователь может решить пойти выпить кофе (если оценка составляет 5-10 минут), пойти на обед (если это 30-60 минут), убить запрос и попробовать что-то другое (возможно, ужесточение ограничений на запрашиваемую информацию ) и т. д. и т. д.

Я не очень знаком с оператором MySQL EXPLAIN - я вижу много информации о том, как его использовать для оптимизации запроса или схемы БД, индексации и т. Д., Но не так много о как использовать его для моей более ограниченной цели - просто сделайте прогноз, принимая БД за заданное (конечно, если прогнозы достаточно надежны, я могу в конечном итоге переключиться на их использование и для выбора между альтернативными формами, которые может принять запрос, но это на будущее: сейчас я был бы очень рад просто показать пользователям оценки производительности для вышеупомянутых целей).

Есть указатели ...?

Ответы [ 3 ]

20 голосов
/ 25 апреля 2009

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

Вам также следует помнить, что если вы используете подзапросы, даже выполнение EXPLAIN может быть медленным (в некоторых случаях почти таким же медленным, как и сам запрос).

Насколько я знаю, MySQL не предоставляет никакого способа оценить время, необходимое для выполнения запроса. Не могли бы вы зарегистрировать время, затрачиваемое на выполнение каждого запроса, а затем построить оценку, основанную на истории предыдущих аналогичных запросов?

11 голосов
/ 25 апреля 2009

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

3 голосов
/ 09 ноября 2015

В MySQL EXPLAIN есть столбец с именем Key. Если в этом столбце что-то есть, это очень хороший показатель, это означает, что запрос будет использовать индекс.

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

Однако

Есть еще одно поле с именем Extra. Это поле иногда содержит текст using_filesort.

Это очень очень плохо. Это буквально означает, что MySQL знает, что запрос будет иметь результирующий набор, больший, чем доступная память, и, следовательно, начнет обмениваться данными на диск для их сортировки.

Заключение

Вместо того, чтобы пытаться предсказать время , которое требуется для запроса, просто посмотрите на эти два индикатора. Если запрос using_filesort, запретите пользователю. И в зависимости от того, насколько строгим вы хотите быть, если в запросе не используются какие-либо ключи, вам также следует это отрицать.

Подробнее о наборе результатов оператора EXPLAIN

...