2014-09-25 3 views
1

Я новичок в оптимизации базы данных MySQL.SELECT COUNT Index

У меня медленный запрос со следующим:

SELECT COUNT(DISTINCT p.product_id) AS total 
    FROM shs_product p 
LEFT JOIN shs_product_description pd 
     ON (p.product_id = pd.product_id) 
LEFT JOIN shs_product_to_store p2s 
     ON (p.product_id = p2s.product_id) 
LEFT JOIN shs_product_to_category p2c 
     ON (p.product_id = p2c.product_id) 
    WHERE pd.language_id = '1' 
     AND p.status = '1' 
     AND p.date_available <= NOW() 
     AND p2s.store_id = '$ 

Может кто-нибудь посоветовать на действия по созданию индекса для ускорения этого запроса? Какой стол и какой столбец вы бы порекомендовали?

Любая помощь будет принята с благодарностью ...

+0

Просто добавить: это и другие запросы вызывают высокую загрузку процессора использования/нагрузки , Я также старательно работаю над файлом my.cnf, но я терплю неудачу. Если бы кто-нибудь мог сделать предложения, я был бы очень благодарен. – Derek

+1

Ваш запрос не делает то, что, по вашему мнению, он делает. Ваши левые соединения на самом деле являются соединениями INNER. Переместите условия на соединениях таблицы в предложение ON упомянутых JOIN. – Sebas

+0

Не уверен, что это улучшит скорость ... но вы уменьшите свои левые соединения до внутренних объединений так, как вы это запросили ... left joins создают нули, когда запись не найдена (внутреннее объединение отфильтровывает их). где p2s.store_ID = '$ означает, что любые записи с нулевыми значениями (записи, включенные, потому что вы оставили соединение) в конечном итоге отфильтровываются на этом аргументе where (IE, этот запрос также может быть всем внутренним соединением). На самом деле это не помощь скорости, а просто хочу убедиться, что вы об этом знаете. Левое соединение с p2c кажется посторонним. – Twelfth

ответ

0

Три наблюдения:

  1. Предложение where является расстегивать внешнее соединение к p2s и pd. Таким образом, вы можете также назвать эти внутренние соединения.
  2. Таблица p2c не используется. Потому что вы делаете count(distinct), вы можете удалить его.
  3. Предположительно, идентификаторы являются целыми числами, так что вам не нужны кавычки

Таким образом, запрос эквивалентно

SELECT COUNT(DISTINCT p.product_id) AS total 
FROM shs_product p JOIN 
    shs_product_description pd 
    ON p.product_id = pd.product_id JOIN 
    shs_product_to_store p2s 
    ON p.product_id = p2s.product_id 
WHERE pd.language_id = 1 AND p.status = 1 AND p.date_available <= NOW() AND 
     p2s.store_id = '$' 

Для этого запроса вы хотите индекс на shs_product(status, date_available). Вам также нужны индексы для столбцов, используемых для объединения, и в предложениях where. Я бы предложил: shs_product_description(product_id, language_id) и shs_product_to_store(product_id, store_id).

Наконец, если предположить, что product_id уникальный индекс в product, вы можете фразу этот запрос, используя exists и count(*) вместо count(distinct):

select count(*) 
from shs_product p 
where p.status = 1 AND p.date_available <= NOW() and 
     exists (select 1 
       from shs_product_description pd 
       where p.product_id = pd.product_id and pd.language_id = 1 
      ) and 
     exists (select 1 
       from shs_product_to_store p2s 
       where p.product_id = p2s.product_id and p2s.store_id = '$' 
      ); 
+0

Спасибо, Гордон. Да, у меня уже есть эти индексы. Мне просто нужно изменить запрос. Отличный совет. Спасибо... – Derek