mirror of
https://github.com/FirebirdSQL/firebird-qa.git
synced 2025-01-22 13:33:07 +01:00
Added/Updated tests\bugs\gh_6915_cs_cz_test.py: Checked on 6.0.0.553, 5.0.2.1580. FB 4.x not passed - see notes. Min_version was set to '5.0'.
This commit is contained in:
parent
d9d02ef184
commit
0de0ff65f4
281
tests/bugs/gh_6915_cs_cz_test.py
Normal file
281
tests/bugs/gh_6915_cs_cz_test.py
Normal file
@ -0,0 +1,281 @@
|
||||
#coding:utf-8
|
||||
|
||||
"""
|
||||
ID: issue-6915-cs-cz
|
||||
ISSUE: https://github.com/FirebirdSQL/firebird/issues/6915
|
||||
TITLE: Performance effect of applying 'DISABLE-COMPRESSIONS=1' in UNICODE collation for LOCALE=cs_CZ
|
||||
DESCRIPTION:
|
||||
Test verifies only PERFORMANCE issues referred to in the ticket #6915. Correctness of ORDER BY is not checked.
|
||||
A pre-build database is used for check, see: files/gh_6915.zip (it was created in FB 4.x with date ~aug-2021).
|
||||
SQL script that was used to fulfill test DB see in the end of this file.
|
||||
We decompress .fbk, restore from it and check that for every testing queries number of indexed reads will not
|
||||
exceed threshold, see 'MAX_IDX_READS_THRESHOLD' (con.info.get_table_access_stats() is used for that).
|
||||
After improvement this threshold could be set to 1.
|
||||
Only columns with attribute 'DISABLE-COMPRESSIONS=1' are checked.
|
||||
NOTES:
|
||||
[23.12.2024] pzotov
|
||||
|
||||
It seems that commit in 4.x (2af9ded1a696a43f5b0bea39a88610287e3ab06c; 04-aug-2021 17:58) had no effect:
|
||||
performance in 4.x remains poort for queries from this test up to recent snapshots (dec-2024).
|
||||
|
||||
Commit in 5.x (cfc09f75a3dea099f54c09808e39fe778457f441; 04-aug-2021 20:25) really SOLVED problem: adding
|
||||
attribute 'DISABLE-COMPRESSIONS=1' causes reducing indexed reads to 0 or 1 for all queries.
|
||||
|
||||
There was commit in 5.x: 171cb7eebc365e301a7384eff96c0e3e069c95cc (date: 17-mar-2022 22:38) - which had
|
||||
further improvement for 'DISABLE-COMPRESSIONS=0' (i.e. when compression is Enabled). Snapshots of FB 5.x
|
||||
before that commit (i.e. up to 5.0.0.425) had poor performance for 'DISABLE-COMPRESSIONS=0', and after
|
||||
this commit (since 5.0.0.426) performance became equal to 'DISABLE-COMPRESSIONS=1'.
|
||||
Because of that, this test verifies performance of only ONE case: 'DISABLE-COMPRESSIONS=1', by comparing
|
||||
of indexed reads for each query with threshold, see MAX_IDX_READS_THRESHOLD.
|
||||
Before improvement related to 'DISABLE-COMPRESSIONS=1', indexed reads were huge for almost all check queries.
|
||||
This is outcome for 5.0.0.126 (31.07.2021):
|
||||
where f_ci_compr_disabled >= 'C' order by f_ci_compr_disabled rows 1 ==> idx reads: 352944
|
||||
where f_ci_compr_disabled >= 'Z' order by f_ci_compr_disabled rows 1 ==> idx reads: 1000000
|
||||
where f_ci_compr_disabled like 'C%' order by f_ci_compr_disabled rows 1 ==> idx reads: 352945
|
||||
where f_ci_compr_disabled like 'Z%' order by f_ci_compr_disabled rows 1 ==> idx reads: 1000000
|
||||
where f_ci_compr_disabled similar to 'C%' order by f_ci_compr_disabled rows 1 ==> idx reads: 352945
|
||||
where f_ci_compr_disabled similar to 'Z%' order by f_ci_compr_disabled rows 1 ==> idx reads: 1000000
|
||||
where f_ci_compr_disabled starting with 'C' order by f_ci_compr_disabled rows 1 ==> idx reads: 352945
|
||||
where f_ci_compr_disabled starting with 'Z' order by f_ci_compr_disabled rows 1 ==> idx reads: 1000000
|
||||
where f_cs_compr_disabled >= 'C' order by f_cs_compr_disabled rows 1 ==> idx reads: 1
|
||||
where f_cs_compr_disabled >= 'Z' order by f_cs_compr_disabled rows 1 ==> idx reads: 0
|
||||
where f_cs_compr_disabled like 'C%' order by f_cs_compr_disabled rows 1 ==> idx reads: 352945
|
||||
where f_cs_compr_disabled like 'Z%' order by f_cs_compr_disabled rows 1 ==> idx reads: 1000000
|
||||
where f_cs_compr_disabled similar to 'C%' order by f_cs_compr_disabled rows 1 ==> idx reads: 352945
|
||||
where f_cs_compr_disabled similar to 'Z%' order by f_cs_compr_disabled rows 1 ==> idx reads: 1000000
|
||||
where f_cs_compr_disabled starting with 'C' order by f_cs_compr_disabled rows 1 ==> idx reads: 352945
|
||||
where f_cs_compr_disabled starting with 'Z' order by f_cs_compr_disabled rows 1 ==> idx reads: 1000000
|
||||
|
||||
Confirmed poor performance on 5.0.0.126 (31.07.2021): all check queries have huge indexed reads,
|
||||
regardless on 'DISABLE-COMPRESSIONS=1' attribute (i.e. it had no effect on performance),
|
||||
execution time was 5...15 seconds for each query.
|
||||
Checked on 5.0.0.129 (05.08.2021 04:25) -- all OK, indexed reads for all queries are 0 or 1.
|
||||
Checked on 6.0.0.553, 5.0.2.1580.
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
import zipfile
|
||||
import locale
|
||||
import pytest
|
||||
from firebird.qa import *
|
||||
from firebird.driver import connect
|
||||
|
||||
db = db_factory(charset = 'utf8')
|
||||
act = python_act('db', substitutions=[('[ \t]+', ' ')])
|
||||
|
||||
tmp_fbk = temp_file('gh_6915.tmp.fbk')
|
||||
tmp_fdb = temp_file('gh_6915.tmp.fdb')
|
||||
|
||||
MAX_IDX_READS_THRESHOLD = 1
|
||||
EXPECTED_MSG = f'Expected. All queries have indexed reads no more than {MAX_IDX_READS_THRESHOLD=}'
|
||||
|
||||
test_sql = """
|
||||
with
|
||||
d as (
|
||||
select '0' as disabled_compression from rdb$database
|
||||
-- union all
|
||||
-- select '1' as disabled_compression from rdb$database
|
||||
)
|
||||
,
|
||||
c as (
|
||||
select 'ci' as case_attribute from rdb$database union all
|
||||
select 'cs' from rdb$database
|
||||
)
|
||||
,o as (
|
||||
select '>=' as search_op from rdb$database union all
|
||||
select 'starting with' from rdb$database union all
|
||||
select 'like' from rdb$database union all
|
||||
select 'similar to' from rdb$database
|
||||
)
|
||||
,e as (
|
||||
select 'C' as letter from rdb$database union all
|
||||
select 'Z' from rdb$database
|
||||
)
|
||||
,f as (
|
||||
select
|
||||
d.*, c.*, o.*, e.*
|
||||
,'select 1 from test where f_' || c.case_attribute || '_compr_' || iif(d.disabled_compression = '0', 'disabled', 'enabled')
|
||||
|| ' ' || trim(o.search_op) || ' '
|
||||
|| ''''
|
||||
|| e.letter
|
||||
|| trim( iif( upper(trim(o.search_op)) in ('>=', upper('starting with')), '', '%') )
|
||||
|| ''''
|
||||
|| ' order by f_' || c.case_attribute || '_compr_' || iif(d.disabled_compression = '0', 'disabled', 'enabled')
|
||||
|| ' rows 1'
|
||||
as query_txt
|
||||
from d
|
||||
cross join c
|
||||
cross join o
|
||||
cross join e
|
||||
)
|
||||
select
|
||||
--case_attribute
|
||||
--,search_op
|
||||
--,letter
|
||||
max(iif(disabled_compression = 0, query_txt, null)) as q_compr_disabled
|
||||
--max(iif(disabled_compression = 1, query_txt, null)) as q_compr_enabled
|
||||
from f
|
||||
group by
|
||||
case_attribute
|
||||
,search_op
|
||||
,letter
|
||||
;
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=5.0.0')
|
||||
def test_1(act: Action, tmp_fbk: Path, tmp_fdb: Path, capsys):
|
||||
|
||||
zipped_fbk_file = zipfile.Path(act.files_dir / 'gh_6915.zip', at = 'gh_6915.fbk')
|
||||
tmp_fbk.write_bytes(zipped_fbk_file.read_bytes())
|
||||
|
||||
act.gbak(switches = ['-rep', str(tmp_fbk), str(tmp_fdb)], combine_output = True, io_enc = locale.getpreferredencoding())
|
||||
assert '' == act.stdout
|
||||
act.reset()
|
||||
reads_map = {}
|
||||
with connect(str(tmp_fdb), user = act.db.user, password = act.db.password, charset = 'utf8') as con:
|
||||
cur = con.cursor()
|
||||
cur2 = con.cursor()
|
||||
|
||||
cur.execute("select rdb$relation_id from rdb$relations where rdb$relation_name = upper('test')")
|
||||
src_relation_id = cur.fetchone()[0]
|
||||
|
||||
cur.execute(test_sql)
|
||||
for r in cur:
|
||||
idx_reads = -1
|
||||
for x_table in con.info.get_table_access_stats():
|
||||
if x_table.table_id == src_relation_id:
|
||||
idx_reads = - (x_table.indexed if x_table.indexed else 0)
|
||||
|
||||
cur2.execute(r[0])
|
||||
cur2.fetchall()
|
||||
|
||||
for x_table in con.info.get_table_access_stats():
|
||||
if x_table.table_id == src_relation_id:
|
||||
idx_reads += (x_table.indexed if x_table.indexed else 0)
|
||||
|
||||
reads_map[ r[0] ] = idx_reads
|
||||
|
||||
|
||||
if max(reads_map.values()) <= MAX_IDX_READS_THRESHOLD:
|
||||
print(EXPECTED_MSG)
|
||||
else:
|
||||
print(f'UNEXPECTED: at least one query has values of indexed reads greater than {MAX_IDX_READS_THRESHOLD=}')
|
||||
for check_qry, idx_reads in reads_map.items():
|
||||
if idx_reads > MAX_IDX_READS_THRESHOLD:
|
||||
print(f'{check_qry=}, {idx_reads=}')
|
||||
|
||||
act.expected_stdout = f"""
|
||||
{EXPECTED_MSG}
|
||||
"""
|
||||
act.stdout = capsys.readouterr().out
|
||||
assert act.clean_stdout == act.clean_expected_stdout
|
||||
|
||||
# End of test.
|
||||
|
||||
################################
|
||||
# SQL with initial DDL and data:
|
||||
################################
|
||||
# create database 'localhost:r:\temp\tmp4test.fdb' default character set utf8;
|
||||
#
|
||||
# create collation u_ci_compr_disabled
|
||||
# for utf8
|
||||
# from unicode
|
||||
# case insensitive
|
||||
# 'LOCALE=cs_CZ;DISABLE-COMPRESSIONS=1'
|
||||
# ;
|
||||
#
|
||||
# create collation u_cs_compr_disabled
|
||||
# for utf8
|
||||
# from unicode
|
||||
# case sensitive
|
||||
# 'LOCALE=cs_CZ;DISABLE-COMPRESSIONS=1'
|
||||
# ;
|
||||
#
|
||||
# create collation u_ci_compr_enabled
|
||||
# for utf8
|
||||
# from unicode
|
||||
# case insensitive
|
||||
# 'LOCALE=cs_CZ;DISABLE-COMPRESSIONS=0'
|
||||
# ;
|
||||
#
|
||||
# create collation u_cs_compr_enabled
|
||||
# for utf8
|
||||
# from unicode
|
||||
# case sensitive
|
||||
# 'LOCALE=cs_CZ;DISABLE-COMPRESSIONS=0'
|
||||
# ;
|
||||
#
|
||||
# create table test (
|
||||
# f_cs_compr_disabled varchar(10) collate u_cs_compr_disabled
|
||||
# ,f_ci_compr_disabled varchar(10) collate u_ci_compr_disabled
|
||||
# ,f_cs_compr_enabled varchar(10) collate u_cs_compr_enabled
|
||||
# ,f_ci_compr_enabled varchar(10) collate u_ci_compr_enabled
|
||||
# );
|
||||
#
|
||||
# set term ^;
|
||||
# create or alter procedure getstr(aorderid bigint) returns (aresult char(10))
|
||||
# as
|
||||
# declare base36chars char(36);
|
||||
# declare mresult varchar(10);
|
||||
# declare id bigint;
|
||||
# declare i int;
|
||||
# begin
|
||||
# base36chars = upper('0123456789abcdefghijklmnopqrstuvwxyz');
|
||||
# mresult = '';
|
||||
# aresult = mresult;
|
||||
# id = aorderid;
|
||||
# while (id > 0) do
|
||||
# begin
|
||||
# i = mod(id, 36);
|
||||
# id = id / 36;
|
||||
# mresult = mresult || substring(base36chars from i + 1 for 1);
|
||||
# end
|
||||
# aresult = left(mresult || '0000000', 7);
|
||||
# suspend;
|
||||
# end
|
||||
# ^
|
||||
#
|
||||
# -- Generate test string data
|
||||
# -- 000000, 100000...900000...A00000...Z00000,
|
||||
# -- 010000, 110000...910000...A10000...Z10000,
|
||||
# -- ...
|
||||
#
|
||||
# execute block
|
||||
# as
|
||||
# declare rowscount int = 100000;
|
||||
# --declare rowscount int = 1000;
|
||||
# declare i int = 0;
|
||||
# declare c int = 0;
|
||||
# declare str varchar(10);
|
||||
# begin
|
||||
# while (c < rowscount) do
|
||||
# begin
|
||||
# select aresult from getstr(:i) into :str;
|
||||
# -- skip y, z
|
||||
# if ( left(str, 1) not in ( upper('y'), upper('z') ) ) then
|
||||
# begin
|
||||
# insert into test(
|
||||
# f_cs_compr_disabled
|
||||
# ,f_ci_compr_disabled
|
||||
# ,f_cs_compr_enabled
|
||||
# ,f_ci_compr_enabled
|
||||
# ) values (
|
||||
# :str
|
||||
# ,:str
|
||||
# ,:str
|
||||
# ,:str
|
||||
# );
|
||||
# c = c + 1;
|
||||
# end
|
||||
# i = i + 1;
|
||||
# end
|
||||
# end
|
||||
# ^
|
||||
# set term ;^
|
||||
# commit;
|
||||
#
|
||||
# create index test_cs_compr_disabled on test (f_cs_compr_disabled);
|
||||
# create index test_ci_compr_disabled on test (f_ci_compr_disabled);
|
||||
# create index test_cs_compr_enabled on test (f_cs_compr_enabled);
|
||||
# create index test_ci_compr_enabled on test (f_ci_compr_enabled);
|
||||
# commit;
|
Loading…
Reference in New Issue
Block a user