Как оптимизировать запрос левого соединения? - PullRequest
3 голосов
/ 22 октября 2010

У меня есть две таблицы: jos_eimcart_customers_addresses и jos_eimcart_customers. Я хочу извлечь все записи из таблицы клиентов и включить информацию об адресе, если она доступна, из таблицы адресов. Запрос работает, но на моем локальном хосте он занял более минуты. На локальном хосте таблицы имеют около 8000 строк в каждой, но в производстве таблицы могут иметь до 25 000 строк в каждой. Есть ли способ оптимизировать это, чтобы это не заняло так много времени? Обе таблицы имеют индекс в поле id, который является первичным ключом. Есть ли какой-то другой индекс, который мне нужно создать, чтобы он работал быстрее? Должна ли таблица адресов иметь индекс в поле customer_id, поскольку это внешний ключ? У меня есть другие запросы к базе данных, которые похожи и выполняются в гораздо больших таблицах, быстрее.

(ИЗМЕНЕНО В ДОБАВИТЬ: на одного клиента может быть несколько записей адресов, поэтому customer_id не является уникальным значением в таблице адресов.)

select 
    c.firstname,
    c.lastname,
    c.email as customer_email, 
    a.email as address_email,
    c.phone as customer_phone,
    a.phone as address_phone,
    a.company,
    a.address1,
    a.address2,
    a.city,
    a.state,a.zip, 
    c.last_signin
from jos_eimcart_customers c
    left join  jos_eimcart_customers_addresses a  
    on c.id = a.customer_id  
order by c.last_signin desc

ИЗМЕНЕНО В ДОБАВИТЬ: Объяснить результаты

id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
==========================================================================================
1  | SIMPLE      |  c    |  ALL |   NULL        | NULL| NULL    |NULL |6175  |Using temporary; Using filesort
---------------------------------------------------------------------------------------
1  | SIMPLE      |  a    |  ALL |   NULL        | NULL| NULL    |NULL |8111  |

Ответы [ 2 ]

7 голосов
/ 22 октября 2010

Вы должны создать индекс для a.customer_id. Это не обязательно должен быть уникальный индекс, но он обязательно должен быть проиндексирован.

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

Попробуйте http://www.dbtuna.com/article.asp?id=14 и http://www.devshed.com/c/a/MySQL/MySQL-Optimization-part-1/2/, чтобы получить немного информации об EXPLAIN.

4 голосов
/ 22 октября 2010

Краткий ответ: Да, customer_id должен иметь индекс.

Лучший ответ. Было бы лучше найти анализатор запросов для MySql и использовать его для определения фактической причины замедления.

Например, вы можете поставить EXPLAIN перед вашим выбором и посмотреть, каковы результаты.

Оптимизация MySQL: запросы и индексы

...