Конференция JPoint 2017

Доклад “Hibernate performance tuning”
Николай Алименков

Обсуждение (1)

Добрый день.
Меня зовут Кирилл и я хотел бы продолжить беседу на тему моего утверждения, что “намного чаще больше результатов приносит оптимизация самого запроса под текущую СУБД, нежели тюнинг ORM”.
Почему я поднял эту тему? за 100+ собеседований java backened developer’ов я видел лишь несколько ребят, которые вообще знают о существовании explain’а и еще меньше, которые знали о том, как этой информацией пользоваться. Возможно это проблемы java community именно в Одессе, но я бы добавил в докладе следующее: “не только не бойтесь писать native SQL в критически важных по производительности местах, но и занимайтесь оптимизацией самого запроса в конкретной БД, которую вы выбрали. Запрос, который исполняется за 20 секунд часто можно переписать так, что при тех же возвращаемых данных, он будет выполняться за 0.1 секунду, не только посредством добавления индекса.” или типа того. Ниже можете найти немного размышлений на тему “одинаковые результаты при разных запросах”, если интересно:

На текущих 5.6 и 5.7 версиях MySQL, что под рукой, у меня не получилось воспроизвести корреляцию в WHERE, которая не правильно разворачивалась EXPLAINом, но все же некоторые результаты я получил (точно помню, что для выборки во внешней части корреляции точно не использовались индексы).
Три запроса с одинаковым результатом, где rel_product_code описывает штрихкоды продукта, lu_product является самим продуктом, у которого есть ссылка на lu_brand, который в свою очередь принадлежит производителю из lu_manufacturer.:
# opt 1, подзапрос с корреляцией внутри
EXPLAIN SELECT rel.product_id
FROM rel_product_code rel
JOIN (SELECT product_id
FROM lu_product
WHERE brand_id IN (SELECT brand_id
FROM lu_brand
WHERE manufacturer_id IN (SELECT manufacturer_id
FROM lu_manufacturer
WHERE manufacturer_desc IN (“test manufacturer 1”, “test manufacturer 2”, “test manufacturer 3”)))) AS inn
ON rel.product_id = inn.product_id;
# opt 2, плоская выборка
EXPLAIN SELECT rel.product_id
FROM rel_product_code rel
JOIN lu_product AS p
ON rel.product_id = p.product_id
JOIN lu_brand AS b
ON p.brand_id = b.brand_id
JOIN lu_manufacturer AS m
ON b.manufacturer_id = m.manufacturer_id
WHERE m.manufacturer_desc IN (“test manufacturer 1”, “test manufacturer 2”, “test manufacturer 3”);
# opt 3, корреляция в корреляции
EXPLAIN SELECT rel.product_id
FROM rel_product_code rel
WHERE rel.product_id IN (SELECT product_id
FROM lu_product
WHERE brand_id IN (SELECT brand_id
FROM lu_brand
WHERE manufacturer_id IN (SELECT manufacturer_id
FROM lu_manufacturer
WHERE manufacturer_desc IN (“test manufacturer 1”, “test manufacturer 2”, “test manufacturer 3”))));

opt2 и opt3 одинаково красиво развернулись на 5.6 и 5.7 версиях в ожидаемые джойны по индексам, но opt1 получил разницу на версиях:
5.6:
1 PRIMARY ALL
1 PRIMARY rel ref
2 DERIVED lu_manufacturer range
2 DERIVED lu_brand ref
2 DERIVED lu_product ref
а в 5.7 оно уже догодалось развернуть подзапрос и сделать его плоским (о том, что может дать DERIVED на больших таблицах вам известно):
1 SIMPLE lu_manufacturer
1 SIMPLE lu_brand
1 SIMPLE lu_product
1 SIMPLE rel

Спасибо за внимание и время, что уделили мне на самой конференции.

P.S. В форме отзыва на http://xpinjection.com/event/%D0%BA%D0%BE%D0%BD%D1%84%D0%B5%D1%80%D0%B5%D0%BD%D1%86%D0%B8%D1%8F-jpoint-2017/ ни файл не прикрепить, ни окошко отзыва не растянуть.

Leave a Reply

Your email address will not be published. Required fields are marked *