Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Непонятки с планом / 4 сообщений из 4, страница 1 из 1
27.05.2017, 05:57
    #39460747
CyberMax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Непонятки с планом
FB 2.5.6. Проверял на 3.0.2 - то же самое.
Проблема с двойным соединением и условием по третьей таблице.
Запрос:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
SELECT
    ABONENT.ID
FROM
    DIR$ABONENT$ABONENT AS ABONENT
--    LEFT JOIN DIR$ABONENT$DEVIANT_BEH AS DEVIANT_BEH ON ABONENT.ID_DEVIANT_BEH = DEVIANT_BEH.ID
    INNER JOIN DIR$HOUSE$HOUSE AS HOUSE ON HOUSE.ID = ABONENT.ID_HOUSE
    INNER JOIN DIR$UNIT$UNIT AS UNIT ON UNIT.ID = HOUSE.ID_UNIT
WHERE
    UNIT.ID = 98


Код: plaintext
PLAN JOIN (UNIT INDEX (PK_DIR$UNIT$UNIT), HOUSE INDEX (FK_DIR$HOUSE$HOUSE_UNIT), ABONENT INDEX (FK_DIR$ABONENT$ABONENT_HOUSE))
Выполняется мгновенно.
Enchanced Info:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
+-------------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
|          Table Name           |  Records  |  Indexed  | Non-Indexed | Updates | Deletes | Inserts | Backouts |  Purges  | Expunges |
|                               |   Total   |   reads   |    reads    |         |         |         |          |          |          |
+-------------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
|DIR$ABONENT$ABONENT            |         0 |       151 |           0 |       0 |       0 |       0 |        0 |        0 |        0 |
|DIR$HOUSE$HOUSE                |         0 |         3 |           0 |       0 |       0 |       0 |        0 |        0 |        0 |
|DIR$UNIT$UNIT                  |         0 |         1 |           0 |       0 |       0 |       0 |        0 |        0 |        0 |
+-------------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+

Но стоит только добавить LEFT JOIN, и FB начинает перебирать абонентов натуралом:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
SELECT
    ABONENT.ID
FROM
    DIR$ABONENT$ABONENT AS ABONENT
    LEFT JOIN DIR$ABONENT$DEVIANT_BEH AS DEVIANT_BEH ON ABONENT.ID_DEVIANT_BEH = DEVIANT_BEH.ID
    INNER JOIN DIR$HOUSE$HOUSE AS HOUSE ON HOUSE.ID = ABONENT.ID_HOUSE
    INNER JOIN DIR$UNIT$UNIT AS UNIT ON UNIT.ID = HOUSE.ID_UNIT
WHERE
    UNIT.ID = 98


Код: plaintext
1.
PLAN JOIN (JOIN (JOIN (ABONENT NATURAL, DEVIANT_BEH INDEX (PK_DIR$ABONENT$DEVIANT_BEH)), HOUSE INDEX (PK_DIR$HOUSE$HOUSE)), UNIT INDEX (PK_DIR$UNIT$UNIT))

Enchanced Info:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
+-------------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
|          Table Name           |  Records  |  Indexed  | Non-Indexed | Updates | Deletes | Inserts | Backouts |  Purges  | Expunges |
|                               |   Total   |   reads   |    reads    |         |         |         |          |          |          |
+-------------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
|DIR$ABONENT$ABONENT            |         0 |         0 |       19733 |       0 |       0 |       0 |        0 |        0 |        0 |
|DIR$ABONENT$DEVIANT_BEH        |         0 |         1 |           0 |       0 |       0 |       0 |        0 |        0 |        0 |
|DIR$HOUSE$HOUSE                |         0 |     19733 |           0 |       0 |       0 |       0 |        0 |        0 |        0 |
|DIR$UNIT$UNIT                  |         0 |       151 |           0 |       0 |       0 |       0 |        0 |        0 |        0 |
+-------------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+


Меняю последовательность таблиц в секции FROM:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
SELECT
    ABONENT.ID
FROM
    DIR$UNIT$UNIT UNIT
    INNER JOIN DIR$HOUSE$HOUSE AS HOUSE ON HOUSE.ID_UNIT = UNIT.ID
    INNER JOIN DIR$ABONENT$ABONENT AS ABONENT ON ABONENT.ID_HOUSE = HOUSE.ID
    LEFT JOIN DIR$ABONENT$DEVIANT_BEH AS DEVIANT_BEH ON ABONENT.ID_DEVIANT_BEH = DEVIANT_BEH.ID
WHERE
    UNIT.ID = 98

Код: plaintext
PLAN JOIN (JOIN (UNIT INDEX (PK_DIR$UNIT$UNIT), HOUSE INDEX (FK_DIR$HOUSE$HOUSE_UNIT), ABONENT INDEX (FK_DIR$ABONENT$ABONENT_HOUSE)), DEVIANT_BEH INDEX (PK_DIR$ABONENT$DEVIANT_BEH))

Получаю такой же план и такую же статистику, как в первом случае.
Это так и должно быть или это баг оптимизатора?
...
Рейтинг: 0 / 0
27.05.2017, 07:29
    #39460751
dimitr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Непонятки с планом
древний баг, давно в трекере. Все INNER-ы по возможности надо группировать вместе и размещать до LEFT-ов - так остается вероятность вменяемого плана.
...
Рейтинг: 0 / 0
27.05.2017, 07:54
    #39460753
CyberMax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Непонятки с планом
dimitr,

Спасибо за ответ, теперь стало понятным составление плана в других запросах. Учту это в генераторе запросов.
А есть примерные сроки, когда это пофиксите? Или это непросто?
...
Рейтинг: 0 / 0
27.05.2017, 09:43
    #39460772
dimitr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Непонятки с планом
непросто, иначе бы давно пофиксили
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Непонятки с планом / 4 сообщений из 4, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]