Repository navigation
Improve performance of ClickBench Q21 by removing the cast #16591
Copy link
Copy link
Closed
Labels
enhancementNew feature or requestNew feature or request
Description
Is your feature request related to a problem or challenge?
When looking into a purported regression in #16575 (comment) I noticed something else about clickbench 21:
SELECT "SearchPhrase", MIN("URL"), COUNT(*) AS c FROM hits WHERE "URL" LIKE '%google%' AND "SearchPhrase" <> '' GROUP BY "SearchPhrase" ORDER BY c DESC LIMIT 10;About 30% of the overall execution time is going to CASTing!
Describe the solution you'd like
Reproduce like this:
cd benchmarks
./bench.sh data clickbench_partitioned
datafusion-cli -c "SELECT \"SearchPhrase\", MIN(\"URL\"), COUNT(*) AS c FROM 'data/hits_partitioned' WHERE \"URL\" LIKE '%google%' AND \"SearchPhrase\" <> '' GROUP BY \"SearchPhrase\" ORDER BY c DESC LIMIT 10;"you can run the explain plan like this
(venv) andrewlamb@Andrews-MacBook-Pro-3:~/Software/datafusion/benchmarks$ datafusion-cli -c "EXPLAIN SELECT \"SearchPhrase\", MIN(\"URL\"), COUNT(*) AS c FROM 'data/hits_partitioned' WHERE \"URL\" LIKE '%google%' AND \"SearchPhrase\" <> '' GROUP BY \"SearchPhrase\" ORDER BY c DESC LIMIT 10;"
DataFusion CLI v48.0.0
+---------------+-------------------------------+
| plan_type | plan |
+---------------+-------------------------------+
| physical_plan | ┌───────────────────────────┐ |
| | │ SortPreservingMergeExec │ |
| | │ -------------------- │ |
| | │ c DESClimit: 10 │ |
| | └─────────────┬─────────────┘ |
| | ┌─────────────┴─────────────┐ |
| | │ SortExec(TopK) │ |
| | │ -------------------- │ |
| | │ c@2 DESC │ |
| | │ │ |
| | │ limit: 10 │ |
| | └─────────────┬─────────────┘ |
| | ┌─────────────┴─────────────┐ |
| | │ ProjectionExec │ |
| | │ -------------------- │ |
| | │ SearchPhrase: │ |
| | │ SearchPhrase │ |
| | │ │ |
| | │ c: count(Int64(1)) │ |
| | │ │ |
| | │ min(data/hits_partitioned │ |
| | │ .URL): │ |
| | │ min(data/hits_partitioned │ |
| | │ .URL) │ |
| | └─────────────┬─────────────┘ |
| | ┌─────────────┴─────────────┐ |
| | │ AggregateExec │ |
| | │ -------------------- │ |
| | │ aggr: │ |
| | │ min(data/hits_partitioned │ |
| | │ .URL), count(1) │ |
| | │ │ |
| | │ group_by: │ |
| | │ SearchPhrase │ |
| | │ │ |
| | │ mode: │ |
| | │ FinalPartitioned │ |
| | └─────────────┬─────────────┘ |
| | ┌─────────────┴─────────────┐ |
| | │ CoalesceBatchesExec │ |
| | │ -------------------- │ |
| | │ target_batch_size: │ |
| | │ 8192 │ |
| | └─────────────┬─────────────┘ |
| | ┌─────────────┴─────────────┐ |
| | │ RepartitionExec │ |
| | │ -------------------- │ |
| | │ partition_count(in->out): │ |
| | │ 16 -> 16 │ |
| | │ │ |
| | │ partitioning_scheme: │ |
| | │ Hash([SearchPhrase@0], 16)│ |
| | └─────────────┬─────────────┘ |
| | ┌─────────────┴─────────────┐ |
| | │ AggregateExec │ |
| | │ -------------------- │ |
| | │ aggr: │ |
| | │ min(data/hits_partitioned │ |
| | │ .URL), count(1) │ |
| | │ │ |
| | │ group_by: │ |
| | │ SearchPhrase │ |
| | │ │ |
| | │ mode: Partial │ |
| | └─────────────┬─────────────┘ |
| | ┌─────────────┴─────────────┐ |
| | │ CoalesceBatchesExec │ |
| | │ -------------------- │ |
| | │ target_batch_size: │ |
| | │ 8192 │ |
| | └─────────────┬─────────────┘ |
| | ┌─────────────┴─────────────┐ |
| | │ FilterExec │ |
| | │ -------------------- │ |
| | │ predicate: │ |
| | │ CAST(URL AS Utf8View) LIKE│ |
| | │ %google% AND │ |
| | │ SearchPhrase │ |
| | │ != │ |
| | └─────────────┬─────────────┘ |
| | ┌─────────────┴─────────────┐ |
| | │ DataSourceExec │ |
| | │ -------------------- │ |
| | │ files: 115 │ |
| | │ format: parquet │ |
| | │ │ |
| | │ predicate: │ |
| | │ CAST(URL AS Utf8View) LIKE│ | <--- this CAST is the problem, for some reason the LIKE is not evaluated natively on the query
| | │ %google% AND │ |
| | │ SearchPhrase │ |
| | │ != │ |
| | └───────────────────────────┘ |
| | |
+---------------+-------------------------------+
1 row(s) fetched.
Elapsed 0.058 seconds.
Describe alternatives you've considered
No response
Additional context
No response
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request

Activity
alamb commentedon Jun 27, 2025
Something strange is going on as I can't reproduce this easily
[-]Improve performance of Q21 by removing the cast[/-][+]Improve performance of ClickBench Q21 by removing the cast[/+]Dandandan commentedon Jun 28, 2025
Wasn't clickbench writing strings as binary columns (an option was added for this)?
Though there is something to say that filtering should not have to validata the utf8-ness.
zhuqi-lucas commentedon Jun 28, 2025
take
zhuqi-lucas commentedon Jun 28, 2025
I want to investigate this issue, thank you @alamb @Dandandan !
zhuqi-lucas commentedon Jun 28, 2025
When i using clickbench benchmark to debug, it does not have cast:
zhuqi-lucas commentedon Jun 28, 2025
Submitted a PR for review, it will make the datafusion-cli consistent with clickbench benchmark, so it should not have extra cast time for datafusion-cli after the PR merged:
#16599
Here is the testing result:
zhuqi-lucas commentedon Jun 28, 2025
Meanwhile as @Dandandan pointed out, this is a good point, if we can remove the filtering for utf8view validation? Need investigation.
zhuqi-lucas commentedon Jun 28, 2025
A minor topic for debugging the benchmark for this ticket:
#16603
I submit a PR try to make benchmark debug mode to use tree format for explain.
Add sorted data benchmark. (#19042)
Add sorted data benchmark. (apache#19042)