powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / select A.*, B.* from A cross B order by indexed_field_of_A rows N: игнорит 'rows N'. Why ?
3 сообщений из 3, страница 1 из 1
select A.*, B.* from A cross B order by indexed_field_of_A rows N: игнорит 'rows N'. Why ?
    #39042763
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hi all

DDL:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
recreate sequence g;
recreate table test_main_data(id int, x int);
recreate table test_unit_args(arg_1 int, arg_2 int);
commit;

insert into test_main_data
select gen_id(g,1), rand()*10
from rdb$types,rdb$types,(select 1 i from rdb$types rows 20);
commit;

insert into test_unit_args(arg_1, arg_2) values( 31415926, 27182818 );
commit;

create descending index test_main_data_x_id_desc on test_main_data(x, id);
commit;

Требуется вывести строку из test_main_data с максимальным значением ключа {x, id} и "приклеить" к ней значения полей таблицы test_unit_args.
Запрос вида:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
select d.x, d.id, u.arg_1, u.arg_2
from (
    select d.x, d.id
    from test_main_data d
    order by x desc,id desc
    rows 1
) d
cross join test_unit_args u;

-- выполнится мгновенно, ибо:
Код: plaintext
1.
2.
3.
4.
5.
Select Expression
    ->  Nested Loop Join (inner)
        ->  First N Records 
            -> Table "TEST_MAIN_DATA" as "D D" Access By ID
                -> Index "TEST_MAIN_DATA_X_ID_DESC" Full Scan
        -> Table "TEST_UNIT_ARGS" as "U" Full Scan

(т.е. в NL поступает только две строки).

А запрос вида:

Код: plaintext
1.
2.
3.
4.
select d.x, d.id, u.arg_1, u.arg_2
from test_main_data d
cross join test_unit_args u
order by x desc,id desc
rows 1

-- будет думкать неск-ко секунд и родит 2.6 млн фетчей. Ибо тут игнорится важный момент: поскольку поля из test_unit_args НЕ участвуют в order-by, их значения в выборке могут быть любыми (но при единственной записи в этой таблице - всё равно одни и те же :)). А раз они м.б. любыми, то можно преобразовывать этот запрос к тому, что приведен первым.

А пока что в это запросе - во:

Код: plaintext
1.
2.
3.
4.
5.
Select Expression
    -> First N Records
        ->  Sort  (record length: 60, key length: 16)
            ->  Nested Loop Join (inner)
                -> Table "TEST_UNIT_ARGS" as "U" Full Scan
                -> Table "TEST_MAIN_DATA" as "D" Full Scan

2 dimitr: можно ли тут что-то сделать или забить "до следующей жизни" ?
...
Рейтинг: 0 / 0
select A.*, B.* from A cross B order by indexed_field_of_A rows N: игнорит 'rows N'. Why ?
    #39042826
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид,

хотел ответить раньше, но sql.ru сегодня лагает не по детски.

Предложения first/rows действуют на оптимизатор как подсказки /* +FIRST_ROWS */. Но для JOIN это работает только тогда, когда соединение происходит по индексу. Может быть пока

Код: sql
1.
2.
3.
4.
select horse.name, color.name
from horse
join color on color.code_color = horse.code_horse
order by horse.name



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
Select Expression
    -> Sort (record length: 180, key length: 56)
        ->  Nested Loop Join (inner)
            -> Table "COLOR" Full Scan
            -> Filter
                -> Table "HORSE" Access By ID
                    -> Bitmap
                        -> Index "PK_HORSE" Unique Scan

как видим оптимизатор зашёл с меньшего потока в результате чего пришлось применить внешнюю сортировку.

Теперь добавим rows 10

Код: sql
1.
2.
3.
4.
5.
select horse.name, color.name
from horse
join color on color.code_color = horse.code_horse
order by horse.name
rows 10



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
Select Expression
    -> First N Records
        ->  Nested Loop Join (inner)
            -> Table "HORSE" Access By ID
                -> Index "HORSE_IDX_NAME" Full Scan
            -> Filter
                -> Table "COLOR" Access By ID
                    -> Bitmap
                        -> Index "PK_COLOR" Unique Scan

здесь оптимизатор поменял стратегию и включилась навигация по индексу

А теперь попробуем провернуть тоже самое с HASH JOIN

Код: sql
1.
2.
3.
4.
5.
select horse.name, color.name
from horse
join color on color.code_color+0 = horse.code_horse+0
order by horse.name
rows 10



и в плане видим всю ту же внешнюю сортировку

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
Select Expression
    -> First N Records
        -> Sort (record length: 180, key length: 56)
            -> Filter
                -> Hash Join (inner)
                    -> Table "HORSE" Full Scan
                    -> Record Buffer (record length: 57)
                        -> Table "COLOR" Full Scan

хотя конкретно в данном случае наверное можно было бы по HORSE можно было бы сделать навигацию по индексу, раз уж она всё равно главная.

А уж cross join оптимизатор думаю не рассматривает и вовсе
...
Рейтинг: 0 / 0
select A.*, B.* from A cross B order by indexed_field_of_A rows N: игнорит 'rows N'. Why ?
    #39042844
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоидможно ли тут что-то сделать или забить "до следующей жизни" ?
забить
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / select A.*, B.* from A cross B order by indexed_field_of_A rows N: игнорит 'rows N'. Why ?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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