Я пытаюсь оптимизировать долговременную хранимую процедуру в моей компании.Из проверки плана запроса, похоже, мы могли бы получить некоторые хорошие результаты, написав запрос, чтобы обеспечить лучшее сокращение раздела.Проблема в том, что, похоже, это создаст очень подробный запрос.По сути, у нас есть несколько таблиц, которые имеют внешний ключ для клиента и «субклиента».Во многих случаях данные не распределяются между клиентами / субклиентами, поэтому мы разделили эти идентификаторы для каждой таблицы.Вот пример запроса, чтобы показать, что я имею в виду:
SELECT ...
FROM CLIENT_PRODUCT cp
INNER JOIN ORDER o ON o.product_id = cp.id
INNER JOIN PRICE_HISTORY ph on ph.product_id = cp.id
WHERE cp.id = ?
Все таблицы имеют внешний ключ, который ссылается на клиента и вспомогательный клиент.Один и тот же клиентский продукт не может принадлежать двум разным клиентам или вспомогательным клиентам (извините. Этот пример использует составленные таблицы и немного надуманен)
Я могу улучшить сокращение раздела, выполнив следующие действия:
SELECT ...
FROM CLIENT_PRODUCT cp
INNER JOIN ORDER o ON o.product_id = cp.id and o.client_id = l_client_id and o.sub_client_id = l_sub_client_id
INNER JOIN PRICE_HISTORY ph on ph.product_id = cp.id and ph.client_id = l_client_id and ph.sub_client_id = l_sub_client_id
WHERE cp.id = ? and cp.client_id = l_client_id and cp.sub_client_id = l_sub_client_id
С этим изменением я просто четко говорю, какой раздел Oracle может просматривать для каждого соединения.Это кажется довольно грубым, потому что я добавил кучу в основном повторяющихся SQL, которые функционально не изменяют то, что возвращается.Этот же шаблон необходимо будет применить ко многим соединениям (больше, чем в примере)
Я знаю, что у нашего приложения есть инвариант, что любой Заказ на Продукт должен принадлежать одному и тому же Клиенту и Субклиенту.Аналогичным образом, любой элемент Price-History должен принадлежать тому же клиенту и субклиенту, что и продукт.Та же идея относится ко многим парам таблиц.Из-за этого инварианта в идеальном мире Oracle сможет вывести клиента и субклиента для каждого объединения из других таблиц в соединении.Кажется, он этого не делает (и я понимаю, что мой конкретный инвариант применим не ко всем).Есть ли способ заставить Oracle выполнить это неявное сокращение раздела без необходимости добавлять все эти дополнительные условия?Похоже, что это добавит много значения всей кодовой базе и устранит необходимость во всех этих «ненужных» явных объединениях.
Существует также возможность того, что я просто полностью продумал / неправильно понял это, так что другие предложения могли быбудь великим.