Есть ли способ оптимизировать этот выбор - PullRequest
0 голосов
/ 28 февраля 2020

Так что у меня есть эта большая избранная ведьма, используемая с союзом. Я думаю, есть ли способ оптимизировать его, потому что теперь он довольно тяжелый.

Как вы можете видеть, основное различие между объединенными таблицами (srv_obj_intermediate и srv_obj_attributes), и у них есть 2 разных oet.code

SELECT * FROM (SELECT soi.value, srv.osp_id, soi.stya_id, eax.estpt_id, eax.discount, seo.id AS sero_id FROM estimate_attr_xref eax
                    JOIN attribute_types attl ON attl.id = eax.attr_id
                    JOIN object_attr_type_links oatl ON oatl.attr_id = attl.id
                    JOIN service_type_attributes sta ON sta.objt_attr_id = oatl.id
                    JOIN srv_obj_intermediate soi ON soi.stya_id = sta.id
                        AND ((soi.value = 0) OR (soi.value = 1 AND festpae_id IS NOT NULL))
                    JOIN service_objects seo ON seo.id = soi.sero_id
                    JOIN services srv ON srv.id = seo.srv_id
                    JOIN order_event oet ON oet.code = 'INTERMEDIATE'
                    WHERE eax.rate = 1 AND eax.ordet_id = oet.id
                    AND eax.objt_attr_id = sta.objt_attr_id) WHERE value = 1

                    UNION

                    SELECT soa.value, srv.osp_id, soa.stya_id, eax.estpt_id, eax.discount, seo.id AS sero_id FROM estimate_attr_xref eax
                    JOIN attribute_types attl ON attl.id = eax.attr_id
                    JOIN object_attr_type_links oatl ON oatl.attr_id = attl.id
                    JOIN service_type_attributes sta ON sta.objt_attr_id = oatl.id
                    JOIN srv_obj_attributes soa ON soa.stya_id = sta.id
                        AND soa.value = 1
                    LEFT JOIN srv_obj_intermediate soi ON soi.stya_id = sta.id
                        AND soi.value = 1
                    JOIN service_objects seo ON seo.id = soa.sero_id
                    JOIN services srv ON srv.id = seo.srv_id
                    JOIN order_event oet ON oet.code = 'INITIAL'
                    WHERE eax.rate = 1 AND eax.ordet_id = oet.id
                    AND eax.objt_attr_id = sta.objt_attr_id AND soi.value IS NULL

1 Ответ

1 голос
/ 28 февраля 2020

Беглый взгляд, без понимания ваших данных, отношений, томов, индексов, секционирования, процессора и т. Д. c.

(1) При первом внешнем выборе (т. Е. Перед UNION) у вас, похоже, есть фильтр WHERE VALUE = 1, где значение фактически равно soe.value. Во внутреннем выборе у вас есть условие ((soi.value = 0) OR (soi.value = 1 AND festpae_id IS NOT NULL)). Разве не достаточно просто использовать soi.value = 1 AND festpae_id IS NOT NULL во внутреннем выборе и избегать внешнего выбора? Какое soi.value вы ищете?

(2) Аналогично, во втором выборе у вас есть LEFT JOIN srv_obj_intermediate soi ON soi.stya_id = sta.id, а далее у вас есть фильтр AND soi.value IS NULL. Опять же, что soi.value вы ищете?

(3) Рассмотрите возможность перемещения предиката фильтра oet.code под предложением where и используйте JOIN order_event oet ON eax.ordet_id = oet.id по причинам, указанным здесь , хотя это не гарантирует улучшения производительности. Вам необходимо проверить, изменяется ли и как план выполнения в каждом конкретном случае.

(4) Обновлены ли статистические данные по всем этим таблицам?

(5) Рассматривали ли вы план ? Вы пропускаете какие-либо объединения и / или имеете в плане декартовы объединения? Вы видите полное сканирование таблицы, когда ожидаете использования индекса или сокращения раздела? Эта белая книга является хорошей отправной точкой, если вы не знакомы с планами объяснения.

...