2013-11-14 6 views
5

Вчера я обнаружил медленный запрос работает на сервере (этот запрос стоит больше, чем на 1 минуту) .Это выглядит следующим образом:Почему этот запрос так медленно работает с MySQL?

select a.* from a 
left join b on a.hotel_id=b.hotel_id and a.hotel_type=b.hotel_type 
where b.hotel_id is null 

Есть 40000+ строка в таблице а и 10000+ строки в таблице б. Уникальный ключ уже был создан на столбцах hotel_id и hotel_type в таблице b, например UNIQUE KEY idx_hotel_id (hotel_id, hotel_type). Так что я использовал ключевое слово для объяснения, чтобы проверить план запроса на этом sql, и я получил результат, похожий на следующий:

   type   key        rows 
1 SIMPLE a ALL  NULL NULL   NULL NULL 36804 
1 SIMPLE b index NULL idx_hotel_id 185  NULL 8353 Using where; Using index; Not exists 

Согласно справочному руководству MySQL, wh en все части индекса используются соединением, а индекс - это индекс PRIMARY KEY или UNIQUE NOT NULL, тип соединения будет «eq_ref». Посмотрите на вторую строку плана запроса, значение типа столбца - «индекс», . Но у меня действительно был уникальный индекс для hotel_id и hotel_type, и оба этих столбца были использованы соединением. Тип соединения «ef_ref» более эффективен, чем тип соединения «ref» и «ref» более эффективен, чем «диапазон», «index» - это последний тип соединения wo wanna hava, кроме «ALL». Это то, о чем я запутался, и я хочу знать, почему тип соединения здесь «index». Надеюсь, я опишу свой вопрос, и я с нетерпением жду ответа от вас, ребята, спасибо!

+2

измените свой выбор. * выберите a.hotel_id, a.hotel_type и скоро. select * не только возвращают данные, но и больше. – errorare

+0

@errorare То, что возвращается, не должно влиять на то, как соединение выполняется. – Barmar

+0

См. Здесь [ссылка] (http://stackoverflow.com/a/3639964/1572987) – errorare

ответ

1

Где Null проверки могут быть медленными, возможно, это так.

select * from a 
where not exists (select 1 from b where a.hotel_id=b.hotel_id and a.hotel_type=b.hotel_type) 

Также: сколько записей вы возвращаете? Если вы возвращаете все записи 36804, это также может замедлить работу.

+0

о 2000+ строках должно быть возвращено. –

+1

@ luxury_zh Может быть, это то, что замедляет его, особенно если «a» содержит много столбцов. Вы можете попробовать указать нужные столбцы (см. Первый комментарий errorare к вашему вопросу) и посмотреть, поможет ли это. Вы можете попытаться ограничить количество возвращаемых записей. – Sam

0

Спасибо всем людям выше! Я нашел способ решить мою проблему самостоятельно. У столбцов hotel_id и hotel_type не было одинакового набора символов. После того как я сделал их как «utf8», мой запрос вернулся, результат примерно в меньшей степени чем 10 миллисекунда. Есть хорошая статья о левом объединении и индексе в MySQL, я настоятельно рекомендую его вам, ребята. Вот сайт: http://explainextended.com/2009/09/18/not-in-vs-not-exists-vs-left-join-is-null-mysql/

Смежные вопросы