Привет.

Не знаю известна ли проблема, поэтому расскажу. У оптимизатора проблемы с оптимизацией запросов с джойнами к (подзапросам или представлениям с внешними соединениями внутри). И представления и 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

Ответить