Вчера обратился ко мне друг с проблемой — при выполнении запроса возникала ошибка
#1104 - The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okay
Пример устранения проблемы в оптимизации запроса — пример очень простой и наглядный, поэтому опубликую весь процесс от а до я.
Запрос следующий
SELECT order_item_id, order_id, order_item_sku, order_item_name, product_quantity, jos_vm_product.product_id, jos_vm_product.product_length, jos_vm_product_mf_xref.manufacturer_id
FROM jos_vm_order_item, jos_vm_product, jos_vm_product_mf_xref
WHERE order_status = 'C' AND product_sku = order_item_sku AND jos_vm_product.product_id=jos_vm_product_mf_xref.product_id AND product_in_stock < 5
Что-то связанное с Joomla Virtuemart (на этом движке у него магазин)- в смысл запроса сильно вникать не стал...
Итак, нам рекомендуют либо увеличить MAX_JOIN_SIZE либо использовать перед выполнением запроса SET SQL_BIG_SELECTS=1
Собственно, так и поступим SET SQL_BIG_SELECTS=1 и запрос.
УРА, запрос выполнился!
Время выполнения (118 всего, Запрос занял 0.3630 сек.)
А теперь подумаем - что же не понравилось SQL движку в данном запросе, а не понравилось в запросе слишком большое количество обрабатываемых присоединяемых строк.
Для анализа запроса - перед ним добавим EXPLAIN и посмотрим результат:
Для обработки запроса движек прошел ВСЕ строки таблицы jos_vm_order_item, а это 146 тыс. строк! не использовав ни одного индекса!
Условие по данной таблицы по полю order_status = 'C' соответственно, делаем по нему индекс
ALTER TABLE jos_vm_order_item
ADD INDEX ( order_status
) ;
смотрим анализ запроса
вместо обработки 146 тыс.строк обрабатывается 117! и повторяем запрос уже без SET SQL_BIG_SELECTS=1
УРА! работает!
Причём скорость выполнения (118 всего, Запрос занял 0.0019 сек.) сильно порадовала - ускорение почти в 200 раз!
Всё! 🙂
P.S. Рекомендую изучить более профессиональную статью по оптимизации запросов с использованием EXPLAIN http://habrahabr.ru/post/211022/