2009-08-15 5 views
3

У меня есть запрос в MySQL (используется в хранимой процедуре), который ищет по имени и другому полю. Когда я использую разные комбинации этих параметров поиска, я получаю быстрые результаты (от 1 до 2 с), но с некоторыми конкретными значениями, я получаю запрос, который занимает 9 с, чтобы возвращать результаты на веб-сайте производства. Ниже то, что я вышел из EXPLAIN заявления:Slow MySQL Query

id, select_type, table, type, possible_keys, key,  key_len, ref, rows, Extra 
-------------------------------------------- 
1, SIMPLE,  Names, ref, IX_Name,  IX_Name, 17,  const, 3173, Using where 

Имени объявлено как VARCHAR (40), а другое поле Unsigned SMALLINT (6). Я использую индекс для первых 15 символов имени (IX_Name), который используется в запросе. Я вижу, что медленные запросы получают довольно большое количество строк для проверки столбца «rows» вывода EXPLAIN.

Я не уверен, что я могу сделать, чтобы улучшить производительность. Есть ли что-то заметно с выходом EXPLAIN выше?

Спасибо, Tim

+2

Возможно, будет неплохо опубликовать медленный исполняемый запрос. – karim79

+1

Не могли бы вы показать свое заявление sql? Кроме того, может быть полезно знать мощность имен, хранящихся в вашей таблице. – DBMarcos99

ответ

3

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

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

+0

Hi Cruachan. Спасибо за ваш ответ. У меня таблица MYISAM 4 миллиона строк, и я обновляю ее каждую неделю. Когда я делаю обновление (около 2000 строк каждую неделю), я затем выполняю следующие утверждения: изменить порядок имен имен таблиц по номеру имени; оптимизировать имена таблиц; анализировать имена таблиц; но я не изменяю индекс или не воссоздаю его ... может быть, проблема в том, что вы сказали, что индекс может быть неуравновешенным? Потому что это объясняет, почему это происходит только с определенными именами. Спасибо, Тим – 2009-08-15 09:31:46

+0

Было бы хорошо отказаться от индекса и воссоздать его, чтобы попробовать. Я никогда не имел базы данных DBA с большой базой данных MySQL, поэтому у меня нет прямого опыта, но, конечно, это верно для нескольких очень больших баз данных Oracle, которые я использовал для администратора. Как правило, люди концентрируются на структуре таблиц и забывают, что индексы также являются структурами хранения, а также должны управляться. – Cruachan

+0

Если вы это сделаете, я буду признателен, если вы опубликуете результат. – Cruachan

1

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

Al Барб Бет Бетси Билл Биф Боб Bonny Buck Bud Карл

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

Теперь, если я ищу «Al», мой индекс возвращает один ряд назад. Затем я сравниваю «Al» в предикате с «Al» в строке, и у меня есть совпадение, поэтому я возвращаю эту строку, и я закончил.

Теперь, если я ищу «Алекс», мой индекс возвращает один ряд назад. Затем я сравниваю «Алекс» в предикате с «Аль» в строке, и у меня нет матча, и больше нет потенциальных матчей, и я закончил.

Но если я ищу «Bud» (или что-нибудь, начинающееся с «B»), мой индекс возвращает девять строк назад. У меня есть девять строк, которые мне нужно прочитать, и сравнить с предикатом, прежде чем я закончу.

ли это:

select substring(name, 1, 15), count(*) 
from names 
group by substring(name, 1, 15); 

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

+0

Спасибо за ваш ответ ... Дело в том, что я ищу полное имя (Fischer), поэтому в этом случае я не думаю, что префикс является проблемой, так как он меньше 15 символов в любом случае ... И я думаю, что имена почти уникальны после 15 символов. Спасибо, Тим – 2009-08-15 10:03:52

0

Я нахожу 3173 строк, чтобы рассмотреть довольно большое количество, предполагая, что вы хотите отдать их пользователю. Если фактическое количество извлеченных записей существенно меньше, вам следует рассмотреть возможность создания дополнительных индексов. Было бы полезно узнать, какие отчеты EXPLAIN относятся к другому поисковому запросу.

2

Похоже, что ваш запрос использует только индекс для одного поля. Вы упомянули, что ищете по имени и «другому полю». MySQL (за исключением самой последней версии в конкретных обстоятельствах) ограничивается одним индексом для вхождения таблицы в запрос. Это означает, что если у вас есть индекс по имени и индексу в другом поле, MySQL, вероятно, придется угадать, какой индекс будет наиболее полезен и игнорировать другой. Похоже, что было бы полезно улучшить структуру запроса или определение индекса. Если ваше имя довольно уникально, и вы получаете 3000 строк в плане объяснения, то либо метаданные в БД не являются хорошими, либо у вас есть много других возможностей в другом поле.

Можете ли вы разместить запрос и схему для таблицы?

Ваши запросы всегда бывают быстрыми или всегда медленными для одного и того же SQL? т. е. если вы ищите Фишера, иногда это быстро, а иногда оно медленное или оно непротиворечиво. Если они согласованы, возможно, это связано с активностью процессора или диска. Если переменная, это, вероятно, связано с другими запросами в БД.

Кроме того, в зависимости от того, что вы выбираете, если вы можете получить свой полный результат в индекс, ваш запрос будет летать, так как ему не нужно будет попадать на диск, чтобы проверить записи. У меня были довольно удивительные улучшения с помощью запросов «using index».

Jacob