У вас есть две проблемы.
Во-первых, с исходным SQL оптимизатор делает оценку количества строк в A со строками, совпадающими с идентификатором в B, которые также имеют совпадающую строку в C. Оценка является неточной, и выбирается неправильный план.
Теперь вы добавляете избыточное условие. Oracle предполагает, что никакие условия не являются действительно избыточными (как если бы они были, интеллектуальный разработчик не включил бы их). Это также предполагает, что каждое условие не зависит от других. Например, выбор, где hair = 'bald' может получить 10% от таблицы, выбор, где пол = 'F', может получить 50%. Oracle предположил бы, что выбор, где hair = 'лысый' и пол = 'F', даст 5% (тогда как в действительности облысение в основном ограничено мужчинами).
Добавляя предикат «избыточность», Oracle будет переоценивать числа или строки, которые нужно исключить, и соответственно выберет план.
Если с помощью избыточного предиката Oracle выбирает лучший план, это говорит о том, что оценки для исходного запроса переоценили число совпадающих строк. Избыточный предикат противопоставляет это заниженной оценке. И в этом случае два ошибки делают право.
Это не решение, которое я бы рекомендовал, но если оно работает .....
PS. Я предполагаю, что типы данных всех идентификаторов совпадают. Если B.ID и C.ID - дата, а A.ID - символ, или наоборот, то возможно иметь несколько строк, где A.ID = B.ID и A.ID = C.ID, но B.ID! = C.ID, потому что неявное преобразование может потерять метки времени.