2012-03-27 5 views
2

Ищете помощь в оптимизации запроса ниже. Кажется, это два узких места в данный момент, которые заставляют его занять около 90 секунд для завершения запроса. Там всего 5000 продуктов, поэтому это не совсем массивная база данных/таблица. Узкими местами являются SQL_CALC_FOUND_ROWS и оператор ORDER BY. Если я удалю оба из них, для выполнения запроса потребуется около секунды. Я попытался удалить SQL_CALC_FOUND_ROWS и запустить инструкцию count(), но это занимает много времени.MySQL Query Optimization

Лучше всего использовать INNER JOIN (с которым я не слишком хорошо знаком) в соответствии со следующим сообщением Stackoverflow? Slow query when using ORDER BY

SELECT SQL_CALC_FOUND_ROWS * 
FROM tbl_products 
LEFT JOIN tbl_link_products_categories ON lpc_p_id = p_id 
LEFT JOIN tbl_link_products_brands ON lpb_p_id = p_id 
LEFT JOIN tbl_link_products_authors ON lpa_p_id = p_id 
LEFT JOIN tbl_link_products_narrators ON lpn_p_id = p_id 
LEFT JOIN tbl_linkfiles ON lf_id = p_id 
AND (
lf_table = 'tbl_products' 
OR lf_table IS NULL 
) 
LEFT JOIN tbl_files ON lf_file_id = file_id 
AND (
file_nameid = 'p_main_image_' 
OR file_nameid IS NULL 
) 
WHERE p_live = 'y' 
ORDER BY p_title_clean ASC, p_title ASC 
LIMIT 0 , 10 
+1

Вам нужно, чтобы все эти соединения были объединены слева? Вы понимаете разницу между внутренним и левым соединениями? – nnichols

+0

Можете ли вы показать нам несколько операторов CREATE TABLE? Какие индексы у вас есть? – Daan

+0

Продукт не обязательно нуждается в категории, бренде, авторе, рассказчике или имеет какие-либо файлы ссылок. Насколько я понимаю, мне нужно использовать LEFT JOIN в этом случае? Потому что, если я использовал INNER JOINS, это не соответствовало бы чему-либо на некоторых элементах? –

ответ

1

Вы можете попробовать уменьшить размер стыков с помощью производной таблицы, чтобы получить отфильтрованный и заказать продукцию, прежде чем присоединиться. Это предполагает, что p_live, p_title_clean и p_title являются поля в вашей таблице tbl_products -

SELECT * 
FROM (SELECT * 
    FROM tbl_products 
    WHERE p_live = 'y' 
    ORDER BY p_title_clean ASC, p_title ASC 
    LIMIT 0 , 10 
) AS tbl_products 
LEFT JOIN tbl_link_products_categories 
    ON lpc_p_id = p_id 
LEFT JOIN tbl_link_products_brands 
    ON lpb_p_id = p_id 
LEFT JOIN tbl_link_products_authors 
    ON lpa_p_id = p_id 
LEFT JOIN tbl_link_products_narrators 
    ON lpn_p_id = p_id 
LEFT JOIN tbl_linkfiles 
    ON lf_id = p_id 
    AND (
     lf_table = 'tbl_products' 
     OR lf_table IS NULL 
    ) 
LEFT JOIN tbl_files 
    ON lf_file_id = file_id 
    AND (
     file_nameid = 'p_main_image_' 
     OR file_nameid IS NULL 
    ) 

Это «удар в темноте», пока не достаточно подробно в вашем вопросе.

+0

Спасибо за это - Надо было немного приспособить его, но это помогло мне понять, как правильно его оптимизировать. –