Оптимизация MySQL для SELECT FROM из нескольких таблиц с некоторыми операциями AND?

0

Этот запрос занимает около 5-10 секунд для запуска, что неприемлемо для рендеринга веб-страницы:

SELECT part . * , brand . * 
FROM  `part` ,  `model2year2part` ,  `brand2subcategory2part` ,  `brand2subcategory` ,  `brand` 
WHERE  `model2year2part`.`model2year_id` =  '9521'
AND  `model2year2part`.`part_id` =  `part`.`id` 
AND  `brand2subcategory`.`subcategory_id` =  '1'
AND  `brand2subcategory2part`.`brand2subcategory_id` =  `brand2subcategory`.`id` 
AND  `brand2subcategory2part`.`part_id` =  `part`.`id` 
AND  `brand`.`id` =  `part`.`brand_id` 

ANSIfied:

SELECT p.*, 
       b.* 
  FROM PART p
  JOIN brand b ON b.id = p.brand_id
  JOIN model2year2part m ON m.part_id = p.id
  JOIN brand2subcategory2part b2p ON b2p.part_id = p.id 
  JOIN brand2subcategory b2 ON b2.id = b2.brand2subcategory_id
 WHERE m.model2year_id = '9521'
   AND b2.subcategory_id = '1'

Независимо от того, что вы подаете на model2year2part. model2year_id и brand2subcategory. subcategory_id в качестве входных данных.

EXPLAIN результаты запроса: http://i.stack.imgur.com/aYtXl.jpg

Я сделал всю возможную индексацию/уникальную индексацию для всех 5 таблиц.

Число полных записей в каждой таблице:

  • часть: 728 534
  • model2year2part: 15 012 595 (это преступник?)
  • brand2subcategory2part: 729 030
  • brand2subcategory: 8,111
  • бренд: 875

Каким может быть преступник? Есть ли способ оптимизировать этот запрос, кроме обновления оборудования?

  • 0
    Вы действительно должны вернуть все столбцы из двух таблиц? Действительно ли необходимы объединения в таблицы категорий ...
  • 0
    Было бы полезно включить план объяснения, чтобы мы могли видеть, что, по мнению оптимизатора запросов, он видит. Просто добавьте EXPLAIN перед SELECT.
Теги:
performance
query-optimization

1 ответ

1
Лучший ответ

Во-первых, я заметил, что выглядит как ошибка в четвертом предложении Join:

ON b2.id = b2.brand2subcategory_id

Я предполагаю, что это должно быть:

ON b2.id = b2p.brand2subcategory_id

Во-вторых, вы можете попытаться вырвать соединения фильтрации из тех, которые необходимы для вывода. Это позволяет вам объяснять только сам подзапрос, чтобы узнать, что может вызвать проблему:

Select P.*, B.*
From Part As P
    Join Brand As B
        On B.Id = P.brand_Id
Where P.part_id In  (
                        Select M1.part_Id
                        From mode2year2part As M1
                                Join brand2subcategory2part As B2P
                                    On B2P.part_id = M1.part_id
                                Join brand2subcategory As B2
                                    On B2.Id = B2P.brand2subcategory_id
                        Where m1.model2year_id = '9521'
                            And B2.subcategory_id = '1'
                        )
  • 0
    MySql не любит вложенные запросы при использовании IN или ANY: jonahellison.com/…
  • 0
    @Calmarius - Внутреннее соединение не эквивалентно предложению IN. Подзапрос IN может легко привести к появлению нескольких строк во внешнем запросе, если его использовать в качестве соединения. Исключение предложений IN или Exists из вашего набора инструментов может серьезно ограничить типы запросов, которые вы можете создавать. Только реальные тесты скажут вам, следует ли изменить структуру данного запроса, чтобы повысить производительность.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню