Skip to content

Commit 2d7d67e

Browse files
Remove special handling of "short" queries - the logic is too ad-hoc, it pollutes the code and is difficult to handle
1 parent bf100e0 commit 2d7d67e

File tree

4 files changed

+7
-96
lines changed

4 files changed

+7
-96
lines changed

docker/test/performance-comparison/README.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,6 @@ Action required for every item -- these are errors that must be fixed.
5050

5151
A query is supposed to run longer than 0.1 second. If your query runs faster, increase the amount of processed data to bring the run time above this threshold. You can use a bigger table (e.g. `hits_100m` instead of `hits_10m`), increase a `LIMIT`, make a query single-threaded, and so on. Queries that are too fast suffer from poor stability and precision.
5252

53-
Sometimes you want to test a query that is supposed to complete "instantaneously", i.e. in sublinear time. This might be `count(*)`, or parsing a complicated tuple. It might not be practical or even possible to increase the run time of such queries by adding more data. For such queries there is a specal comparison mode which runs them for a fixed amount of time, instead of a fixed number of iterations like we do normally. This mode is inferior to the normal mode, because the influence of noise and overhead is higher, which leads to less precise and stable results.
54-
55-
If it is impossible to increase the run time of a query and it is supposed to complete "immediately", you have to explicitly mark this in the test. To do so, add a `short` attribute to the query tag in the test file: `<query short="1">...`. The value of the `short` attribute is evaluated as a python expression, and substitutions are performed, so you can write something like `<query short="{column1} = {column2}">select count(*) from table where {column1} > {column2}</query>`, to mark only a particular combination of variables as short.
56-
57-
This table shows queries for which the `short` marking is not consistent with the actual query run time -- i.e., a query runs for a normal time but is marked as `short`, or it runs faster than normal but is not marked as `short`.
58-
5953
#### Partial Queries
6054
Action required for the cells marked in red.
6155

docker/test/performance-comparison/compare.sh

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,6 @@ do
376376
sed -n "s/^report-threshold\t/$test_name\t/p" < "$test_file" >> "analyze/report-thresholds.tsv"
377377
sed -n "s/^skipped\t/$test_name\t/p" < "$test_file" >> "analyze/skipped-tests.tsv"
378378
sed -n "s/^display-name\t/$test_name\t/p" < "$test_file" >> "analyze/query-display-names.tsv"
379-
sed -n "s/^short\t/$test_name\t/p" < "$test_file" >> "analyze/marked-short-queries.tsv"
380379
sed -n "s/^partial\t/$test_name\t/p" < "$test_file" >> "analyze/partial-queries.tsv"
381380
done
382381

@@ -817,23 +816,18 @@ create view query_runs as select * from file('analyze/query-runs.tsv', TSV,
817816
-- calculate and check the average query run time in the report.
818817
-- We have to be careful, because we will encounter:
819818
-- 1) partial queries which run only on one server
820-
-- 2) short queries which run for a much higher number of times
821819
-- 3) some errors that make query run for a different number of times on a
822820
-- particular server.
823821
--
824822
create view test_runs as
825823
select test,
826824
-- Default to 7 runs if there are only 'short' queries in the test, and
827825
-- we can't determine the number of runs.
828-
if((ceil(medianOrDefaultIf(t.runs, not short), 0) as r) != 0, r, 7) runs
826+
if((ceil(median(t.runs), 0) as r) != 0, r, 7) runs
829827
from (
830828
select
831829
-- The query id is the same for both servers, so no need to divide here.
832830
uniqExact(query_id) runs,
833-
(test, query_index) in
834-
(select * from file('analyze/marked-short-queries.tsv', TSV,
835-
'test text, query_index int'))
836-
as short,
837831
test, query_index
838832
from query_runs
839833
group by test, query_index
@@ -918,41 +912,6 @@ create table all_tests_report engine File(TSV, 'report/all-queries.tsv')
918912
from queries order by test, query_index;
919913
920914
921-
-- Report of queries that have inconsistent 'short' markings:
922-
-- 1) have short duration, but are not marked as 'short'
923-
-- 2) the reverse -- marked 'short' but take too long.
924-
-- The threshold for 2) is significantly larger than the threshold for 1), to
925-
-- avoid jitter.
926-
create view shortness
927-
as select
928-
(test, query_index) in
929-
(select * from file('analyze/marked-short-queries.tsv', TSV,
930-
'test text, query_index int'))
931-
as marked_short,
932-
time, test, query_index, query_display_name
933-
from (
934-
select right time, test, query_index from queries
935-
union all
936-
select time_median, test, query_index from partial_query_times
937-
) times
938-
left join query_display_names
939-
on times.test = query_display_names.test
940-
and times.query_index = query_display_names.query_index
941-
;
942-
943-
create table inconsistent_short_marking_report
944-
engine File(TSV, 'report/unexpected-query-duration.tsv')
945-
as select
946-
multiIf(marked_short and time > 0.1, '\"short\" queries must run faster than 0.02 s',
947-
not marked_short and time < 0.02, '\"normal\" queries must run longer than 0.1 s',
948-
'') problem,
949-
marked_short, time,
950-
test, query_index, query_display_name
951-
from shortness
952-
where problem != ''
953-
;
954-
955-
956915
--------------------------------------------------------------------------------
957916
-- various compatibility data formats follow, not related to the main report
958917
@@ -1432,4 +1391,3 @@ esac
14321391
# Print some final debug info to help debug Weirdness, of which there is plenty.
14331392
jobs
14341393
pstree -apgT
1435-

docker/test/performance-comparison/perf.py

Lines changed: 6 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -168,17 +168,12 @@ def substitute_parameters(query_templates, other_templates=[]):
168168

169169

170170
# Build a list of test queries, substituting parameters to query templates,
171-
# and reporting the queries marked as short.
172171
test_queries = []
173-
is_short = []
174172
for e in root.findall("query"):
175-
new_queries, [new_is_short] = substitute_parameters(
176-
[e.text], [[e.attrib.get("short", "0")]]
173+
new_queries = substitute_parameters(
174+
[e.text]
177175
)
178176
test_queries += new_queries
179-
is_short += [eval(s) for s in new_is_short]
180-
181-
assert len(test_queries) == len(is_short)
182177

183178
# If we're given a list of queries to run, check that it makes sense.
184179
for i in args.queries_to_run or []:
@@ -194,11 +189,6 @@ def substitute_parameters(query_templates, other_templates=[]):
194189
print(test_queries[i])
195190
exit(0)
196191

197-
# Print short queries
198-
for i, s in enumerate(is_short):
199-
if s:
200-
print(f"short\t{i}")
201-
202192
# If we're only asked to print the settings, do that and exit. These are settings
203193
# for clickhouse-benchmark, so we print them as command line arguments, e.g.
204194
# '--max_memory_usage=10000000'.
@@ -458,27 +448,10 @@ def do_create(connection, index, queries):
458448
# already.
459449
run += 1
460450

461-
# Try to run any query for at least the specified number of times,
462-
# before considering other stop conditions.
463-
if run < args.runs:
464-
continue
465-
466-
# For very short queries we have a special mode where we run them for at
467-
# least some time. The recommended lower bound of run time for "normal"
468-
# queries is about 0.1 s, and we run them about 10 times, giving the
469-
# time per query per server of about one second. Run "short" queries
470-
# for longer time, because they have a high percentage of overhead and
471-
# might give less stable results.
472-
if is_short[query_index]:
473-
if server_seconds >= 8 * len(this_query_connections):
474-
break
475-
# Also limit the number of runs, so that we don't go crazy processing
476-
# the results -- 'eqmed.sql' is really suboptimal.
477-
if run >= 500:
478-
break
479-
else:
480-
if run >= args.runs:
481-
break
451+
# We break if all the min stop conditions are met (arg.runs iterations)
452+
# and at lest one of the max stop conditions is met (8 seconds or 500 iterations)
453+
if run >= args.runs and (server_seconds >= 8 * len(this_query_connections) or run >= 500):
454+
break
482455

483456
client_seconds = time.perf_counter() - start_seconds
484457
print(f"client-time\t{query_index}\t{client_seconds}\t{server_seconds}")

docker/test/performance-comparison/report.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -393,20 +393,6 @@ def add_errors_explained():
393393
]
394394
)
395395

396-
unmarked_short_rows = tsvRows("report/unexpected-query-duration.tsv")
397-
error_tests += len(unmarked_short_rows)
398-
addSimpleTable(
399-
"Unexpected Query Duration",
400-
["Problem", 'Marked as "short"?', "Run time, s", "Test", "#", "Query"],
401-
unmarked_short_rows,
402-
)
403-
if unmarked_short_rows:
404-
errors_explained.append(
405-
[
406-
f'<a href="#{currentTableAnchor()}">Some queries have unexpected duration</a>'
407-
]
408-
)
409-
410396
def add_partial():
411397
rows = tsvRows("report/partial-queries-report.tsv")
412398
if not rows:

0 commit comments

Comments
 (0)