From 9ae7b9a024be6a97d48a554a76bca08425ca7b5c Mon Sep 17 00:00:00 2001 From: Caetano Sauer Date: Thu, 13 Aug 2026 11:25:33 +0200 Subject: [PATCH] Hyper: load native benchmark data from Parquet Switch the native Hyper benchmark from the 81 GB CSV input to the 15 GB single-file Parquet dataset. This reduces the measured load time from 327.0 seconds to 187.1 seconds (43%) while producing the same 99,997,497 rows and the same logical results for all 43 ClickBench queries. --- hyper/benchmark.sh | 2 +- hyper/create.sql | 112 +++++++++++++++++++++++++++++++++++++++++++++ hyper/load | 12 +++-- 3 files changed, 120 insertions(+), 6 deletions(-) diff --git a/hyper/benchmark.sh b/hyper/benchmark.sh index f61f185e49..a33527ee30 100755 --- a/hyper/benchmark.sh +++ b/hyper/benchmark.sh @@ -1,3 +1,3 @@ #!/bin/bash -export BENCH_DOWNLOAD_SCRIPT="download-hits-csv" +export BENCH_DOWNLOAD_SCRIPT="download-hits-parquet-single" exec ../lib/benchmark-common.sh diff --git a/hyper/create.sql b/hyper/create.sql index 3b376b0624..267a35b710 100644 --- a/hyper/create.sql +++ b/hyper/create.sql @@ -1,3 +1,7 @@ +create temp external table hits_parquet +for 'hits.parquet' +with (format => 'parquet', binary_as_text => true, immutable => true); + create table hits ( watchid bigint not null, javaenable smallint not null, @@ -106,3 +110,111 @@ create table hits ( clid integer not null, assumed primary key (counterid, eventdate, userid, eventtime, watchid) ); + +INSERT INTO hits SELECT +"WatchID", +"JavaEnable", +"Title", +"GoodEvent", +to_timestamp("EventTime") AS "EventTime", +(DATE '1970-01-01' + "EventDate"::integer) AS "EventDate", +"CounterID", +"ClientIP", +"RegionID", +"UserID", +"CounterClass", +"OS", +"UserAgent", +"URL", +"Referer", +"IsRefresh", +"RefererCategoryID", +"RefererRegionID", +"URLCategoryID", +"URLRegionID", +"ResolutionWidth", +"ResolutionHeight", +"ResolutionDepth", +"FlashMajor", +"FlashMinor", +"FlashMinor2", +"NetMajor", +"NetMinor", +"UserAgentMajor", +"UserAgentMinor", +"CookieEnable", +"JavascriptEnable", +"IsMobile", +"MobilePhone", +"MobilePhoneModel", +"Params", +"IPNetworkID", +"TraficSourceID", +"SearchEngineID", +"SearchPhrase", +"AdvEngineID", +"IsArtifical", +"WindowClientWidth", +"WindowClientHeight", +"ClientTimeZone", +to_timestamp("ClientEventTime") AS "ClientEventTime", +"SilverlightVersion1", +"SilverlightVersion2", +"SilverlightVersion3", +"SilverlightVersion4", +"PageCharset", +"CodeVersion", +"IsLink", +"IsDownload", +"IsNotBounce", +"FUniqID", +"OriginalURL", +"HID", +"IsOldCounter", +"IsEvent", +"IsParameter", +"DontCountHits", +"WithHash", +"HitColor", +to_timestamp("LocalEventTime") AS "LocalEventTime", +"Age", +"Sex", +"Income", +"Interests", +"Robotness", +"RemoteIP", +"WindowName", +"OpenerName", +"HistoryLength", +"BrowserLanguage", +"BrowserCountry", +"SocialNetwork", +"SocialAction", +"HTTPError", +"SendTiming", +"DNSTiming", +"ConnectTiming", +"ResponseStartTiming", +"ResponseEndTiming", +"FetchTiming", +"SocialSourceNetworkID", +"SocialSourcePage", +"ParamPrice", +"ParamOrderID", +"ParamCurrency", +"ParamCurrencyID", +"OpenstatServiceName", +"OpenstatCampaignID", +"OpenstatAdID", +"OpenstatSourceID", +"UTMSource", +"UTMMedium", +"UTMCampaign", +"UTMContent", +"UTMTerm", +"FromTag", +"HasGCLID", +"RefererHash", +"URLHash", +"CLID" +FROM hits_parquet; diff --git a/hyper/load b/hyper/load index 9c34e7d839..b3cd219b19 100755 --- a/hyper/load +++ b/hyper/load @@ -1,8 +1,8 @@ #!/bin/bash -# Create hits.hyper and COPY hits.csv into it, using the PERSISTENT Hyper +# Create hits.hyper and load hits.parquet into it, using the PERSISTENT Hyper # server started by ./start (descriptor in server.endpoint). Loading through # the already-running server avoids briefly running two hyperd instances -# (each of which would try to claim up to 80% of RAM) during the heavy COPY. +# (each of which would try to claim up to 80% of RAM) during the heavy load. set -e # shellcheck disable=SC1091 @@ -19,9 +19,11 @@ with open("server.endpoint") as f: endpoint = Endpoint(connection_descriptor=descriptor, user_agent="clickbench") with Connection(endpoint, 'hits.hyper', CreateMode.CREATE_AND_REPLACE) as connection: - connection.execute_command(open("create.sql").read()) - connection.execute_command("copy hits from 'hits.csv' with (format csv)") + # The Hyper API accepts one statement per execute_command call. + for command in open("create.sql").read().split(";"): + if command.strip(): + connection.execute_command(command) PY -rm -f hits.csv +rm -f hits.parquet sync