Привет.
Не знаю известна ли проблема, поэтому расскажу. У оптимизатора проблемы
с оптимизацией запросов с джойнами к (подзапросам или представлениям с
внешними соединениями внутри). И представления и Derived tables
оптимизируются одинаково, поэтому приведу пример для вторых:
1) Есть процедура:
CONVERT_IDS_TO_ROWS(IDS VARCHAR(32700)) RETURNS (ID INTEGER)
её задача распарсить строку чисел, разделённых запятой, и вернуть эти
числа в табличном виде. Там внутри нет ни одного запроса, только парсинг
строки.
2) Есть две связанные таблицы, которые можно соединить по INNER и по
LEFT JOIN (без разницы как):
SELECT O."Id", O."ObjectId", O."TagName", T."Permanent", T."MatchesCount"
FROM "TaggedObjects" O
JOIN "Tags" T ON T."Id" = O."TagId"
WHERE O."ObjectName" = 'FeedItem'
3) У меня на запрос 2 есть представление, но для упрощения понимания я
вместо него использовал Derived tables, поскольку они дают такой же
результат:
-----------------------------------------------------------------------
Запрос А, работает великолепно:
SELECT TOB.*
FROM CONVERT_IDS_TO_ROWS('54319218, 54319223') R
JOIN (
SELECT O."Id", O."ObjectId", O."TagName", T."Permanent", T."MatchesCount"
FROM "TaggedObjects" O
JOIN "Tags" T ON T."Id" = O."TagId"
WHERE O."ObjectName" = 'FeedItem'
) TOB ON TOB."ObjectId" = R.ID
PLAN JOIN (JOIN (CONVERT_IDS_TO_ROWS NATURAL, TOB O INDEX
(UNQ1_TaggedObjects)), TOB T INDEX (PK_Tags))
-----------------------------------------------------------------------
Запрос Б, делает какой-то странный по-моему план. При этом
осуществляется полный перебор по таблице "TaggedObjects".
SELECT TOB.*
FROM CONVERT_IDS_TO_ROWS('54319218, 54319223') R
JOIN (
SELECT O."Id", O."ObjectId", O."TagName", T."Permanent", T."MatchesCount"
FROM "TaggedObjects" O
LEFT JOIN "Tags" T ON T."Id" = O."TagId"
WHERE O."ObjectName" = 'FeedItem'
) TOB ON TOB."ObjectId" = R.ID
PLAN MERGE (SORT (JOIN (TOB O NATURAL, TOB T INDEX (PK_Tags))), SORT
(CONVERT_IDS_TO_ROWS NATURAL))
-----------------------------------------------------------------------
Запрос В, работает отлично (я вместо джойна с процедурой передал
значения ID в список IN)
SELECT TOB.*
FROM CONVERT_IDS_TO_ROWS('54319218, 54319223') R
JOIN (
SELECT O."Id", O."ObjectId", O."TagName", T."Permanent", T."MatchesCount"
FROM "TaggedObjects" O
LEFT JOIN "Tags" T ON T."Id" = O."TagId"
WHERE O."ObjectName" = 'FeedItem'
) TOB ON TOB."ObjectId" IN (54319218, 54319223)
PLAN JOIN (CONVERT_IDS_TO_ROWS NATURAL, JOIN (TOB O INDEX
(UNQ1_TaggedObjects, UNQ1_TaggedObjects), TOB T INDEX (PK_Tags)))
-----------------------------------------------------------------------
Запрос Г, тоже работает великолепно. То есть если нету представления и
подзапроса, то оптимизатор всё хорошо разруливает:
SELECT O.*
FROM CONVERT_IDS_TO_ROWS('54319218, 54319223') R
JOIN "TaggedObjects" O ON O."ObjectId" = R.ID
LEFT JOIN "Tags" T ON T."Id" = O."TagId"
WHERE O."ObjectName" = 'FeedItem'
PLAN JOIN (JOIN (CONVERT_IDS_TO_ROWS NATURAL, O INDEX
(UNQ1_TaggedObjects)), T INDEX (PK_Tags))
Впроверял на FB 2.0.1 и на 2.0