mirror of
https://github.com/FirebirdSQL/firebird-qa.git
synced 2025-01-22 21:43:06 +01:00
113 lines
3.0 KiB
Python
113 lines
3.0 KiB
Python
#coding:utf-8
|
|
|
|
"""
|
|
ID: issue-5759
|
|
ISSUE: 5759
|
|
TITLE: Bad performance for NULLs filtering inside a navigational index scan
|
|
DESCRIPTION:
|
|
See prototype and explanations for this test in CORE_5435.fbt
|
|
Confirmed improvement:
|
|
|
|
3.0.2.32643, 4.0.0.563:
|
|
**********
|
|
PLAN (TEST ORDER TEST_F01_ID)
|
|
1 records fetched
|
|
1143 ms, 2375 read(s), 602376 fetch(es) ---------------- poor :(
|
|
Table Natural Index
|
|
****************************************************
|
|
TEST 300000
|
|
|
|
3.0.2.32708, 4.0.0.572:
|
|
**********
|
|
PLAN (TEST ORDER TEST_F01_ID)
|
|
0 ms, 22 read(s), 63 fetch(es) --------------------------- cool :)
|
|
Table Natural Index
|
|
****************************************************
|
|
TEST 20
|
|
JIRA: CORE-5489
|
|
FBTEST: bugs.core_5489
|
|
"""
|
|
|
|
import pytest
|
|
from firebird.qa import *
|
|
|
|
db = db_factory(page_size=8192)
|
|
|
|
act = python_act('db')
|
|
|
|
FETCHES_THRESHOLD = 80
|
|
|
|
init_sql = """
|
|
recreate table test
|
|
(
|
|
id int not null,
|
|
f01 int,
|
|
f02 int
|
|
);
|
|
|
|
set term ^;
|
|
create or alter procedure sp_add_init_data(a_rows_to_add int)
|
|
as
|
|
declare n int;
|
|
declare i int = 0;
|
|
begin
|
|
n = a_rows_to_add;
|
|
while (i < n) do
|
|
begin
|
|
insert into test(id, f01, f02) values(:i, nullif(mod(:i, :n/20), 0), iif(mod(:i,3)<2, 0, 1))
|
|
returning :i+1 into i;
|
|
end
|
|
end
|
|
^
|
|
set term ^;
|
|
commit;
|
|
|
|
execute procedure sp_add_init_data(300000);
|
|
commit;
|
|
|
|
create index test_f01_id on test(f01, id);
|
|
create index test_f02_only on test(f02);
|
|
commit;
|
|
"""
|
|
|
|
test_script = """
|
|
set list on;
|
|
select count(*) cnt_check
|
|
from (
|
|
select *
|
|
from test
|
|
where f01 -- ###################################################################
|
|
IS NULL -- <<< ::: NB ::: we check here 'f01 is NULL', exactly as ticket says.
|
|
and f02=0 -- ###################################################################
|
|
order by f01, id
|
|
) ;
|
|
"""
|
|
|
|
trace = ['time_threshold = 0',
|
|
'log_statement_finish = true',
|
|
'print_plan = true',
|
|
'print_perf = true',
|
|
'log_initfini = false',
|
|
]
|
|
|
|
@pytest.mark.version('>=3.0.2')
|
|
def test_1(act: Action):
|
|
act.isql(switches=[], input=init_sql)
|
|
with act.trace(db_events=trace):
|
|
act.reset()
|
|
act.isql(switches=[], input=test_script)
|
|
# Process trace
|
|
run_with_plan = ''
|
|
num_of_fetches = 99999999
|
|
for line in act.trace_log:
|
|
if line.lower().startswith('plan ('):
|
|
run_with_plan = line.strip().upper()
|
|
elif 'fetch(es)' in line:
|
|
words = line.split()
|
|
for k in range(len(words)):
|
|
if words[k].startswith('fetch'):
|
|
num_of_fetches = int(words[k-1])
|
|
# Check
|
|
assert run_with_plan == 'PLAN (TEST ORDER TEST_F01_ID)'
|
|
assert num_of_fetches < FETCHES_THRESHOLD
|