2012-02-22 2 views
4

У меня есть следующие таблицы:Multiple слева присоединяется и производительность

продуктов - 4500 записей

поле: идентификатор, Код, имя, псевдоним, цена, special_price, количество, по убыванию, фото, manufacturer_id, model_id , хиты, издательство

products_attribute_rel - 35000 записей

Поля: идентификатор, product_id, attribute_id, attribute_val_id

attribute_values ​​- 243 записей

поля: идентификатор, attr_id, стоимость, заказ

производителей - 29 записей

Поля: идентификатор, название, издательство

модели - 946 записей

поля: ID, manufacturer_id, название, издательство

Так я получаю данные из этих таблиц с помощью одного запроса:

SELECT jp.*, 
     jm.id AS jm_id, 
     jm.title AS jm_title, 
     jmo.id AS jmo_id, 
     jmo.title AS jmo_title 
FROM `products` AS jp 
LEFT JOIN `products_attribute_rel` AS jpar ON jpar.product_id = jp.id 
LEFT JOIN `attribute_values` AS jav ON jav.attr_id = jpar.attribute_val_id 
LEFT JOIN `manufacturers` AS jm ON jm.id = jp.manufacturer_id 
LEFT JOIN `models` AS jmo ON jmo.id = jp.model_id 
GROUP BY jp.id HAVING COUNT(DISTINCT jpar.attribute_val_id) >= 0 

Этот запрос является медленным, как ад. Для обработки требуется несколько секунд mysql. Итак, как можно было бы улучшить этот запрос? С небольшими кусками данных он отлично работает . Но я думаю, что все руины products_attribute_rel стол, который имеет 35000 записей.

Ваша помощь будет оценена.

РЕДАКЦИЯ

EXPLAIN Результаты SELECT запроса:

EXPLAIN results of the SELECT query

+1

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

+0

Используете ли вы какой-либо метод индексации, например b-tree? – DonCallisto

+2

поставьте 'EXPLAIN' перед' SELECT' и покажите нам результат. Это может помочь нам выяснить, что такое узкие места. – Mike

ответ

8

Проблема заключается в том, что MySQL использует тип соединения ALL для 3 таблиц. Это означает, что MySQL выполняет 3 полных сканирования таблицы, объединяет все возможности, прежде чем сортировать те, которые не соответствуют оператору ON. Чтобы получить гораздо более быстрый тип соединения (например, eq_ref), вы должны поместить индекс в coloumns, которые используются в операциях ON.

Следует помнить, что не рекомендуется указывать индекс для всех возможных колоний.Многие индексы ускоряют операторы SELECT, однако они также создают накладные расходы, поскольку индекс должен храниться и управляться. Это означает, что манипуляционные запросы, такие как UPDATE и DELETE, намного медленнее. Я видел запросы, удаляющие всего 1000 записей за полчаса. Это компромисс, когда вам нужно решать, что происходит чаще и что более важно.

Чтобы получить дополнительную информацию о типах соединений MySQL, просмотрите this.
Подробнее об индексах here.

+0

Спасибо, Майк. Я ставлю индексы, и теперь все работает просто отлично. – Bounce

1

Таблица данных не являются настолько огромным, что он принимает сотни секунд. Что-то не так с табличной схемой. Пожалуйста, сделайте правильную индексацию. Это ускорит ускорение.

0
select distinct 
jm.id AS jm_id, 
jm.title AS jm_title, 
jmo.id AS jmo_id, 
jmo.title AS jmo_title 
from products jp, 
products_attribute_rel jpar, 
attribute_values jav, 
manufacturers jm 
models jmo 
where jpar.product_id = jp.id 
and jav.attr_id = jpar.attribute_val_id 
and jm.id = jp.manufacturer_id 
and jmo.id = jp.model_id 

Вы можете сделать это, если хотите выбрать все данные. Надеюсь, что это работает.

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