2015-04-25 3 views
0

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

Select * from tblretailerusers where (company_id=169 or company_id in (select id from tblretailercompany where multi_ret_id='169')) and (id in (Select contact_person_1 from tbllocations where status=1 and (retailer_comp_id=169 or retailer_comp_id in (select id from tblretailercompany where multi_ret_id='169'))) OR id in(Select contact_person_2 from tbllocations where status=1 and (retailer_comp_id=169 or retailer_comp_id in (select id from tblretailercompany where multi_ret_id='169')))) and (last_login is not null) 

В нем есть три таблицы, в которых есть Розничный торговец, их местоположение и их Пользователь. Стандартная информация пользователя. Каждый розничный торговец может иметь дочерний розничный торговец, поэтому таблица Retailer имеет идентификатор розничного продавца. В настоящее время каждая таблица имеет около 6K записей, и вся таблица имеет первичный ключ как Auto increment и, как я знаю, они также индексируются. в поле «Таблица пользователей» индексируется.

Теперь этот запрос принимает < 1 сек., Что хорошо, но теперь клиент хочет найти пользователя, чьи идентификаторы электронной почты начинаются с определенной буквы, например a и b. Как только я добавляю это к запросу, он начинает принимать около 50-60 секунд. Я создаю указатель на поле Email, которое не является уникальным, и новый запрос выглядит

Select * from tblretailerusers where (company_id=169 or company_id in (select id from tblretailercompany where multi_ret_id='169')) and (id in (Select contact_person_1 from tbllocations where status=1 and (retailer_comp_id=169 or retailer_comp_id in (select id from tblretailercompany where multi_ret_id='169'))) OR  id in(Select contact_person_2 from tbllocations where status=1 and (retailer_comp_id=169 or retailer_comp_id in (select id from tblretailercompany where multi_ret_id='169')))) and (last_login is not null) and email REGEXP '^A|^B' 

Я пытаюсь использовать Объяснить, как в версии запроса и тот интересный факт, я замечаю, что в начальной строке таблицы это не показывают любое значение для possible_key, где, когда мы используем ключ Primary id, вы можете найти в таблице User, а также поле Index on Email. Вот Объяснить запроса:

enter image description here

Я пытаюсь воссоздать индекс, текущий у меня есть индекс, который используют идентификатор CompanyID и адрес электронной почты в один индекс, кроме первичного ключа в таблице пользователей. Я также создаю Index on Company Tables, но ничто не ускоряет его. Таблица пользователей - MyISAM.

Другой вопрос: как я могу пропустить Sub Query для Child Company Search, так как вы можете видеть, что он использовался трижды в запросе выше.

EDIT: Причина, по которой я использую REGEXP в моем запросе, заключается в том, что когда я пытаюсь выполнить Like 'A%', это было даже медленно с этой опцией.

Редактировать Я только что проверил с last_login is null вместо last_login is not null, а результаты занимают менее 5 секунд. Не похожи на Null или Not Null?

ответ

0

Вместо того, чтобы использовать регулярные выражения:

and email REGEXP '^A|^B' 

... попробовать простой LIKE:

and (email like 'A%' or email like 'B%') 

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

+0

жаль, что я забыл упомянуть, что я выбираю 'regexp' после того, как' Like% 'займет еще больше времени для работы. –

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