2014-01-04 3 views
5

У меня есть три таблицы: продукт (записи 10k), product_attribute (записи 4k) и product_value (записи 2m). product и product_attribute подключаются через product_value. Я хочу получить конкретный продукт (например, product_id = 001) и его соответствующее имя атрибута и значение атрибута. Сначала я стараюсьMySQL-запросы очень медленные, даже используя INNER JOIN вместо IN

SELECT product.product_id, product_attribute.attribute_name, product_value.attribute_value 

FROM product, product_attribute, product_value 

WHERE product.product_id = 001 AND product.product_id = product_value.product_id AND product_attribute.product_attribute_id IN (SELECT product_value.product_attribute_id FROM product_value WHERE product_value.product_id = 001) 

Но это очень медленно. Тогда я использовал INNER JOIN вместо IN

SELECT product.product_id, product_attribute.attribute_name, product_value.attribute_value FROM product 

INNER JOIN product_value ON product.product_id = 001 AND product.product_id = product_value.product_id 

INNER JOIN product_attribute ON product_attribute.product_attribute_id = product_value.product_attribute_id WHERE product.product_id = 001 

Но это все еще очень медленно: запрос возвращает 31 строк в 36 минут!

Есть ли лучшее решение этой проблемы?

Объясняя запрос дает:

*************************** 1. row *********** 
      id: 1 
    select_type: SIMPLE 
     table: product_attribute 
     type: ALL 
possible_keys: NULL 
      key: NULL 
     key_len: NULL 
      ref: NULL 
     rows: 5247 
     Extra: 
*************************** 2. row *********** 
      id: 1 
    select_type: SIMPLE 
     table: product 
     type: ALL 
possible_keys: NULL 
      key: NULL 
     key_len: NULL 
      ref: NULL 
     rows: 91818 
     Extra: Using where; Using join buffer 
*************************** 3. row *********** 
      id: 1 
    select_type: SIMPLE 
     table: product_value 
     type: ALL 
possible_keys: NULL 
      key: NULL 
     key_len: NULL 
      ref: NULL 
     rows: 1731016 
     Extra: Using where; Using join buffer 
+0

Какую информацию вы пытаетесь получить от этого запроса? – Marcos

+0

Объясните свой запрос и обновите его. – Suresh

+0

Есть ли у вас индексы на ваших таблицах? –

ответ

4

Попробуйте это:

SELECT p.product_id, pa.attribute_name, pv.attribute_value 
FROM product p 
INNER JOIN product_value pv ON p.product_id = pv.product_id 
INNER JOIN product_attribute pa ON pa.product_attribute_id = pv.product_attribute_id 
WHERE p.product_id = 001 

Выполнить этот запрос, и если вы по-прежнему сталкивается запрос медленно, чем добавить вас EXPLAIN план выше запроса

Чтобы повысить производительность, вам необходимо создать индекс для столбцов.

  1. Создание индекса на product_id колонке таблицы product_value

  2. Создание индекса на product_attribute_id колонке таблицы product_value

+0

Это не помогло ... Я опубликовал 'EXPLAIN'. Кажется, что запрос полностью просматривал таблицы, которые подключены. – user3138073

+0

@ user3138073 Проверьте мой обновленный ответ. Проверьте производительность запроса после создания индексов. Если вы все еще находите более медленную производительность, чем снова, проверьте план 'EXPLAIN' вашего запроса и обновления в своем вопросе –

+0

@ user3138073 Пожалуйста, обновите свои скрипты' create table' для этих трех таблиц –