Skip to content

Ignore NULL when navigating through an index to calculate MIN/MAX #8744

@sim1984

Description

@sim1984

Firebird 5.0.3

CREATE TABLE TEST (
  ID BIGINT GENERATED BY DEFAULT AS IDENTITY,
  A INT,
  CONSTRAINT PK_TEST_ID PRIMARY KEY(ID)
);

CREATE INDEX TEST_A_IDX ON TEST(A);

SET TERM^;

EXECUTE BLOCK
AS
DECLARE N INTEGER = 0;
BEGIN
  WHILE (N < 100) DO
  BEGIN
    N = N + 1;
    INSERT INTO TEST(A) VALUES(:N);
  END
END^

SET TERM;^

COMMIT;

Let's try to execute the following SQL query.

SELECT MIN(A) FROM TEST;
Select Expression
    -> Aggregate
        -> Table "TEST" Access By ID
            -> Index "TEST_A_IDX" Full Scan

         MIN
============
           1

Current memory = 284733488
Delta memory = 96
Max memory = 284810128
Elapsed time = 0.002 sec
Buffers = 32768
Reads = 0
Writes = 0
Fetches = 3

Very good result. Now let's add NULL values ​​to column A.

SET TERM^;

EXECUTE BLOCK
AS
DECLARE N INTEGER = 0;
BEGIN
  WHILE (N < 1000) DO
  BEGIN
    N = N + 1;
    INSERT INTO TEST(A) VALUES(NULL);
  END
END^

SET TERM;^

COMMIT;

SELECT MIN(A) FROM TEST;
Select Expression
    -> Aggregate
        -> Table "TEST" Access By ID
            -> Index "TEST_A_IDX" Full Scan

         MIN
============
           1

Current memory = 284818048
Delta memory = 0
Max memory = 284881152
Elapsed time = 0.002 sec
Buffers = 32768
Reads = 0
Writes = 0
Fetches = 2003

Apparently, unnecessary readings of records with the NULL key are being performed. If you change the query a little, the performance will return to normal.

SELECT MIN(A) FROM TEST WHERE A > 0;
Select Expression
    -> Aggregate
        -> Filter
            -> Table "TEST" Access By ID
                -> Index "TEST_A_IDX" Range Scan (lower bound: 1/1)

         MIN
============
           1

Current memory = 284832992
Delta memory = 176
Max memory = 284881152
Elapsed time = 0.002 sec
Buffers = 32768
Reads = 0
Writes = 0
Fetches = 3

It would be nice if the optimizer itself set lower/upper bounds when calculating MIN/MAX and ignored scanning of NULL keys in the index.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions