Вы можете создать индекс на основе функций
CREATE INDEX idx_rel_obj_id
ON( substr( object_id1, 1, 3 ),
substr( object_id2, 1, 3 ) );
Но тогда ваши запросы должны будут использовать те же вызовы функций
SELECT *
FROM rel
WHERE substr( rel.object_id1, 1, 3 ) = '001'
AND substr( rel.object_id2, 1, 3 ) = '002'
Обычно вы создаете пользовательские функции(т.е. get_object_type), которые были помечены как детерминированные и будут использовать эти пользовательские функции как в определении индекса, так и в запросах, чтобы гарантировать, что кто-то случайно не использует другую конструкцию для получения первых трех символов полячто помешало бы использовать индекс на основе функций.
Все это, как говорится, наличие столбца в таблице, где первые три символа представляют некоторый другой элемент данных, является нарушением базовой нормализации.Почти всегда лучше хранить первые три символа в отдельном столбце, чем пытаться анализировать составной столбец во время выполнения.