Skip to content

Non-correlated sub-query is evaluated multiple times if it is based on a view rather than on an equivalent derived table. #7863

@pavel-zotov

Description

@pavel-zotov

Consider script:

set list on;
set bail on;
 
shell del g:\temp\tmp4test.fdb 2>nul;
create database 'localhost:g:\temp\tmp4test.fdb' user sysdba password 'masterkey';
 
create view v_aux as select 1 i from rdb$fields rows 50;
 
create table test(id int);
insert into test(id) select row_number()over() from rdb$types rows 100;
commit;
 
select count(*) as cnt_directly from test where (select i from (select 1 i from rdb$fields rows 50) rows 1) >= 0; --- case [ 1 ]
select count(*) as cnt_via_view from test where (select i from v_aux rows 1) >= 0; --- case [ 2 ]

The only difference between [1] and [2] is that "[2]" uses VIEW in the non-correlated sub-query rather than "(select 1 i from rdb$fields rows 50)" in "[1]".

Trace for "case [1]":

select count(*) as cnt_directly from test where
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sub-query (invariant)
    -> Singularity Check
        -> First N Records
            -> First N Records
                -> Table "RDB$FIELDS" Full Scan
Select Expression
    -> Aggregate
        -> Filter (preliminary)
            -> Table "TEST" Full Scan
1 records fetched
      0 ms, 106 fetch(es)
 
Table                              Natural
***********************************************
RDB$FIELDS                               1
TEST                                   100

So far - so good. We have "Sub-query (invariant)" in explained plan thus RBD$FIELDS is queried only once.

No let's look on trace for "case [2]":

select count(*) as cnt_via_view from test where (select i from v_aux rows 1) >= 0
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sub-query
    -> Singularity Check
        -> First N Records
            -> First N Records
                -> Table "RDB$FIELDS" as "V_AUX RDB$FIELDS" Full Scan
Select Expression
    -> Aggregate
        -> Filter (preliminary)
            -> Table "TEST" Full Scan
1 records fetched
      0 ms, 205 fetch(es)
 
Table                              Natural     Index    Update    Insert    Delete
**********************************************************************************
RDB$FIELDS                             101
TEST                                   100

No "Sub-query (invariant)" --> 101 reads from RDB$FIELDS.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions