diff options
author | gvit <gvit@ydb.tech> | 2022-10-19 13:54:23 +0300 |
---|---|---|
committer | gvit <gvit@ydb.tech> | 2022-10-19 13:54:23 +0300 |
commit | 2dbcdae6cc17c38d4ffed47ac9dcab10be6de9d2 (patch) | |
tree | dc2c622ff725760e8a76bbc6668b994bffb68eb7 | |
parent | 741e5f61cf7dcc3f87d87ed03a6b7ee7508cf857 (diff) | |
download | ydb-2dbcdae6cc17c38d4ffed47ac9dcab10be6de9d2.tar.gz |
PR from branch users/gvit/refactor-clickbench
-rw-r--r-- | ydb/public/lib/ydb_cli/commands/CMakeLists.txt | 44 | ||||
-rw-r--r-- | ydb/public/lib/ydb_cli/commands/click_bench.cpp | 357 | ||||
-rw-r--r-- | ydb/public/lib/ydb_cli/commands/click_bench.h | 137 | ||||
-rw-r--r-- | ydb/public/lib/ydb_cli/commands/click_bench_queries.sql | 172 | ||||
-rw-r--r-- | ydb/public/lib/ydb_cli/commands/click_bench_schema.sql | 112 | ||||
-rw-r--r-- | ydb/public/lib/ydb_cli/commands/stock_workload.h | 2 | ||||
-rw-r--r-- | ydb/public/lib/ydb_cli/commands/ydb_workload.cpp | 2 |
7 files changed, 825 insertions, 1 deletions
diff --git a/ydb/public/lib/ydb_cli/commands/CMakeLists.txt b/ydb/public/lib/ydb_cli/commands/CMakeLists.txt index b8b2152f9e4..01ecb9370cc 100644 --- a/ydb/public/lib/ydb_cli/commands/CMakeLists.txt +++ b/ydb/public/lib/ydb_cli/commands/CMakeLists.txt @@ -34,8 +34,10 @@ target_link_libraries(clicommands PUBLIC cpp-client-ydb_table cpp-client-ydb_topic ydb_types-credentials-login + library-cpp-resource ) target_sources(clicommands PRIVATE + ${CMAKE_SOURCE_DIR}/ydb/public/lib/ydb_cli/commands/click_bench.cpp ${CMAKE_SOURCE_DIR}/ydb/public/lib/ydb_cli/commands/stock_workload.cpp ${CMAKE_SOURCE_DIR}/ydb/public/lib/ydb_cli/commands/kv_workload.cpp ${CMAKE_SOURCE_DIR}/ydb/public/lib/ydb_cli/commands/ydb_sdk_core_access.cpp @@ -56,3 +58,45 @@ target_sources(clicommands PRIVATE ${CMAKE_SOURCE_DIR}/ydb/public/lib/ydb_cli/commands/ydb_workload.cpp ${CMAKE_SOURCE_DIR}/ydb/public/lib/ydb_cli/commands/ydb_yql.cpp ) + +add_global_library_for(clicommands.global clicommands) +target_link_libraries(clicommands.global PUBLIC + contrib-libs-cxxsupp + yutil + cpp-histogram-hdr + cpp-protobuf-json + cpp-regex-pcre + cpp-threading-local_executor + kikimr_backup + ydb-library-workload + public-lib-operation_id + common + lib-ydb_cli-dump + lib-ydb_cli-import + topic + cpp-client-draft + cpp-client-ydb_discovery + cpp-client-ydb_export + cpp-client-ydb_import + cpp-client-ydb_monitoring + cpp-client-ydb_operation + cpp-client-ydb_persqueue_public + cpp-client-ydb_proto + cpp-client-ydb_scheme + cpp-client-ydb_table + cpp-client-ydb_topic + ydb_types-credentials-login + library-cpp-resource +) +target_sources(clicommands.global PRIVATE + ${CMAKE_BINARY_DIR}/ydb/public/lib/ydb_cli/commands/b27fa204a2892655fc6f34eb84a6343b.cpp +) +resources(clicommands.global + ${CMAKE_BINARY_DIR}/ydb/public/lib/ydb_cli/commands/b27fa204a2892655fc6f34eb84a6343b.cpp + INPUTS + ${CMAKE_SOURCE_DIR}/ydb/public/lib/ydb_cli/commands/click_bench_queries.sql + ${CMAKE_SOURCE_DIR}/ydb/public/lib/ydb_cli/commands/click_bench_schema.sql + KEYS + click_bench_queries.sql + click_bench_schema.sql +) diff --git a/ydb/public/lib/ydb_cli/commands/click_bench.cpp b/ydb/public/lib/ydb_cli/commands/click_bench.cpp new file mode 100644 index 00000000000..9d76e89b7c6 --- /dev/null +++ b/ydb/public/lib/ydb_cli/commands/click_bench.cpp @@ -0,0 +1,357 @@ +#include <util/string/split.h> +#include <util/stream/file.h> +#include <util/string/strip.h> +#include <util/string/printf.h> +#include <util/folder/pathsplit.h> +#include <library/cpp/json/json_writer.h> + +#include <library/cpp/http/simple/http_client.h> +#include <library/cpp/string_utils/base64/base64.h> + +#include "click_bench.h" + +using namespace NYdb; +using namespace NYdb::NTable; + + +static void ThrowOnError(const TStatus& status) { + if (!status.IsSuccess()) { + ythrow yexception() << "Operation failed with status " << status.GetStatus() << ": " + << status.GetIssues().ToString(); + } +} + +static NJson::TJsonValue GetQueryLabels(ui32 queryId) { + NJson::TJsonValue labels(NJson::JSON_MAP); + labels.InsertValue("query", Sprintf("Query%02u", queryId)); + return labels; +} + +static NJson::TJsonValue GetSensorValue(TStringBuf sensor, TDuration& value, ui32 queryId) { + NJson::TJsonValue sensorValue(NJson::JSON_MAP); + sensorValue.InsertValue("sensor", sensor); + sensorValue.InsertValue("value", value.MilliSeconds()); + sensorValue.InsertValue("labels", GetQueryLabels(queryId)); + return sensorValue; +} + +static NJson::TJsonValue GetSensorValue(TStringBuf sensor, double value, ui32 queryId) { + NJson::TJsonValue sensorValue(NJson::JSON_MAP); + sensorValue.InsertValue("sensor", sensor); + sensorValue.InsertValue("value", value); + sensorValue.InsertValue("labels", GetQueryLabels(queryId)); + return sensorValue; +} + +void TClickHouseBench::Init() { + TString createSql = NResource::Find("click_bench_schema.sql"); + TTableClient client(Driver); + + SubstGlobal(createSql, "{table}", FullTablePath()); + ThrowOnError(client.RetryOperationSync([createSql](TSession session) { + return session.ExecuteSchemeQuery(createSql).GetValueSync(); + })); +} + + +TClickHouseBench::TTestInfo TClickHouseBench::AnalyzeTestRuns(const TVector<TDuration>& timings) { + TTestInfo info; + + if (timings.empty()) { + return info; + } + + info.ColdTime = timings[0]; + + if (timings.size() > 1) { + ui32 sum = 0; + for (size_t j = 1; j < timings.size(); ++j) { + if (info.Max < timings[j]) { + info.Max = timings[j]; + } + if (!info.Min || info.Min > timings[j]) { + info.Min = timings[j]; + } + sum += timings[j].MilliSeconds(); + } + info.Mean = (double) sum / (double) (timings.size() - 1); + if (timings.size() > 2) { + double variance = 0; + for (size_t j = 1; j < timings.size(); ++j) { + variance += (info.Mean - timings[j].MilliSeconds()) * (info.Mean - timings[j].MilliSeconds()); + } + variance = variance / (double) (timings.size() - 2); + info.Std = sqrt(variance); + } + } + + return info; +} + +TClickBenchCommandInit::TClickBenchCommandInit() + : TYdbCommand("init", {"i"}, "Initialize table") +{} + +void TClickBenchCommandInit::Config(TConfig& config) { + NYdb::NConsoleClient::TClientCommand::Config(config); + config.SetFreeArgsNum(0); + + config.Opts->AddLongOption("table", "Table name to work with") + .Optional() + .RequiredArgument("NAME") + .DefaultValue("hits") + .StoreResult(&Table); + config.Opts->AddLongOption('p', "path", "Relative path to table") + .Optional() + .RequiredArgument("PATH") + .Handler1T<TStringBuf>([this](TStringBuf arg) { + if (arg.StartsWith('/')) { + ythrow NLastGetopt::TUsageException() << "Path must be relative"; + } + Path = arg; + }); +}; + +int TClickBenchCommandInit::Run(TConfig& config) { + auto driver = CreateDriver(config); + + TClickHouseBench chb(driver, config.Database, Path, Table); + chb.Init(); + Cout << "Table created" << Endl; + driver.Stop(true); + return 0; +}; + + +TClickBenchCommandRun::TClickBenchCommandRun() + : TYdbCommand("run", {"b"}, "Perform benchmark") +{} + +void TClickBenchCommandRun::Config(TConfig& config) { + TClientCommand::Config(config); + config.SetFreeArgsNum(0); + config.Opts->AddLongOption('o', "output", "Save queries output to file") + .Optional() + .RequiredArgument("FILE") + .DefaultValue("results.out") + .StoreResult(&OutFilePath); + config.Opts->AddLongOption('n', "iterations", "Iterations count (without cold-start run)") + .DefaultValue(0) + .StoreResult(&IterationsCount); + config.Opts->AddLongOption('j', "json", "Json report file name") + .DefaultValue("") + .StoreResult(&JsonReportFileName); + config.Opts->AddLongOption("disable-llvm", "disable llvm") + .NoArgument() + .SetFlag(&DisableLlvm); + config.Opts->AddLongOption("enable-pushdown", "enabled pushdown") + .NoArgument() + .SetFlag(&EnablePushdown); + config.Opts->AddLongOption('f', "ext-queries-file", "File with external queries. Separated by ';'") + .DefaultValue("") + .StoreResult(&ExternalQueriesFile); + config.Opts->AddLongOption("table", "Table name to work with") + .Optional() + .RequiredArgument("NAME") + .DefaultValue("hits") + .StoreResult(&Table); + config.Opts->AddLongOption("path", "Relative path to table") + .Optional() + .RequiredArgument("PATH") + .Handler1T<TStringBuf>([this](TStringBuf arg) { + if (arg.StartsWith('/')) { + ythrow NLastGetopt::TUsageException() << "Path must be relative"; + } + Path = arg; + }); + config.Opts->AddLongOption('q', "ext-query", "String with external queries. Separated by ';'") + .DefaultValue("") + .StoreResult(&ExternalQueries); + + auto fillTestCases = [](TStringBuf line, std::function<void(ui32)>&& op) { + for (const auto& token : StringSplitter(line).Split(',').SkipEmpty()) { + TStringBuf part = token.Token(); + TStringBuf from, to; + if (part.TrySplit('-', from, to)) { + ui32 begin = FromString(from); + ui32 end = FromString(to); + while (begin <= end) { + op(begin); + ++begin; + } + } else { + op(FromString<ui32>(part)); + } + } + }; + + auto includeOpt = config.Opts->AddLongOption("include", + "Run only specified queries (ex.: 1,2,3,5-10,20)") + .Optional() + .Handler1T<TStringBuf>([this, fillTestCases](TStringBuf line) { + QueriesToRun.clear(); + fillTestCases(line, [this](ui32 q) { + QueriesToRun.insert(q); + }); + }); + auto excludeOpt = config.Opts->AddLongOption("exclude", + "Run all queries except given ones (ex.: 1,2,3,5-10,20)") + .Optional() + .Handler1T<TStringBuf>([this, fillTestCases](TStringBuf line) { + fillTestCases(line, [this](ui32 q) { + QueriesToSkip.emplace(q); + }); + }); + + config.Opts->MutuallyExclusiveOpt(includeOpt, excludeOpt); +}; + + +int TClickBenchCommandRun::Run(TConfig& config) { + auto driver = CreateDriver(config); + TClickHouseBench chb(driver, config.Database, Path, Table); + std::unique_ptr<IQueryRunner> runner; + runner = std::make_unique<TStreamQueryRunner>(driver); + const bool okay = chb.RunBench(*runner, *this); + driver.Stop(true); + return !okay; +}; + + +bool TClickHouseBench::RunBench(IQueryRunner& queryRunner, const TBenchContext& context) +{ + TOFStream outFStream{context.OutFilePath}; + + TStringStream report; + report << "Results for " << (context.IterationsCount + 1) << " iterations" << Endl; + report << "+---------+----------+---------+---------+----------+---------+" << Endl; + report << "| Query # | ColdTime | Min | Max | Mean | Std |" << Endl; + report << "+---------+----------+---------+---------+----------+---------+" << Endl; + + NJson::TJsonValue jsonReport(NJson::JSON_ARRAY); + const bool collectJsonSensors = !context.JsonReportFileName.empty(); + const TString queries = queryRunner.GetQueries(FullTablePath(), context.GetExternalQueries()); + i32 queryN = 0; + bool allOkay = true; + for (auto& qtoken : StringSplitter(queries).Split(';')) { + if (!context.NeedRun(++queryN)) { + continue; + } + const TString query = context.PatchQuery(qtoken.Token()); + + TVector<TDuration> timings; + timings.reserve(1 + context.IterationsCount); + + Cout << Sprintf("Query%02u", queryN) << ":" << Endl; + Cerr << "Query text:\n" << Endl; + Cerr << query << Endl << Endl; + + for (ui32 i = 0; i <= context.IterationsCount; ++i) { + auto t1 = TInstant::Now(); + auto res = queryRunner.Execute(query); + + auto duration = TInstant::Now() - t1; + + Cout << "\titeration " << i << ":\t"; + if (res.second == "") { + Cout << "ok\t" << duration << " seconds" << Endl; + timings.emplace_back(duration); + } else { + allOkay = false; + Cout << "failed\t" << duration << " seconds" << Endl; + Cerr << queryN << ": " << query << Endl + << res.first << res.second << Endl; + } + + if (i == 0) { + outFStream << queryN << ": " << Endl + << res.first << res.second << Endl << Endl; + } + } + + auto testInfo = AnalyzeTestRuns(timings); + report << Sprintf("| %02u | %8zu | %7zu | %7.zu | %8.2f | %7.2f |", queryN, + testInfo.ColdTime.MilliSeconds(), testInfo.Min.MilliSeconds(), testInfo.Max.MilliSeconds(), + testInfo.Mean, testInfo.Std) << Endl; + if (collectJsonSensors) { + jsonReport.AppendValue(GetSensorValue("ColdTime", testInfo.ColdTime, queryN)); + jsonReport.AppendValue(GetSensorValue("Min", testInfo.Min, queryN)); + jsonReport.AppendValue(GetSensorValue("Max", testInfo.Max, queryN)); + jsonReport.AppendValue(GetSensorValue("Mean", testInfo.Mean, queryN)); + jsonReport.AppendValue(GetSensorValue("Std", testInfo.Std, queryN)); + } + } + + report << "+---------+----------+---------+---------+----------+---------+" << Endl; + + Cout << Endl << report.Str() << Endl; + Cout << "Results saved to " << context.OutFilePath << Endl; + + if (collectJsonSensors) { + TOFStream jStream{context.JsonReportFileName}; + NJson::WriteJson(&jStream, &jsonReport, /*formatOutput*/ true); + jStream.Finish(); + Cout << "Report saved to " << context.JsonReportFileName << Endl; + } + + return allOkay; +} + +TString TClickHouseBench::FullTablePath() const { + TPathSplitUnix prefixPathSplit(Database); + prefixPathSplit.AppendComponent(Path); + prefixPathSplit.AppendComponent(Table); + return prefixPathSplit.Reconstruct(); +} + + +TString TStreamQueryRunner::GetQueries(const TString& fullTablePath, const TString& externalQueries) { + TString queries = externalQueries ? externalQueries : NResource::Find("click_bench_queries.sql"); + SubstGlobal(queries, "{table}", "`" + fullTablePath + "`"); + return queries; +} + +std::pair<TString, TString> TStreamQueryRunner::Execute(const TString& query) { + TStreamExecScanQuerySettings settings; + settings.CollectQueryStats(ECollectQueryStatsMode::Full); + auto it = SqClient.StreamExecuteScanQuery(query, settings).GetValueSync(); + ThrowOnError(it); + return ResultToYson(it); +} + +std::pair<TString, TString> TStreamQueryRunner::ResultToYson(NTable::TScanQueryPartIterator& it) { + TStringStream out; + TStringStream err_out; + NYson::TYsonWriter writer(&out, NYson::EYsonFormat::Text, ::NYson::EYsonType::Node, true); + writer.OnBeginList(); + + for (;;) { + auto streamPart = it.ReadNext().GetValueSync(); + if (!streamPart.IsSuccess()) { + if (!streamPart.EOS()) { + err_out << streamPart.GetIssues().ToString() << Endl; + } + break; + } + + if (streamPart.HasResultSet()) { + auto result = streamPart.ExtractResultSet(); + auto columns = result.GetColumnsMeta(); + + NYdb::TResultSetParser parser(result); + while (parser.TryNextRow()) { + writer.OnListItem(); + writer.OnBeginList(); + for (ui32 i = 0; i < columns.size(); ++i) { + writer.OnListItem(); + FormatValueYson(parser.GetValue(i), writer); + } + writer.OnEndList(); + out << "\n"; + } + } + } + + writer.OnEndList(); + return {out.Str(), err_out.Str()}; +} diff --git a/ydb/public/lib/ydb_cli/commands/click_bench.h b/ydb/public/lib/ydb_cli/commands/click_bench.h new file mode 100644 index 00000000000..69b28218893 --- /dev/null +++ b/ydb/public/lib/ydb_cli/commands/click_bench.h @@ -0,0 +1,137 @@ +#pragma once + +#include <ydb/public/sdk/cpp/client/ydb_table/table.h> +#include <ydb/public/lib/yson_value/ydb_yson_value.h> +#include <ydb/public/lib/ydb_cli/common/root.h> +#include <util/generic/set.h> + +#include "ydb_command.h" + +struct IQueryRunner { + virtual ~IQueryRunner() = default; + virtual TString GetQueries(const TString& fullTablePath, const TString& externalQueries) = 0; + virtual std::pair<TString, TString> Execute(const TString& query) = 0; +}; + +class TBenchContext { +protected: + TSet<ui32> QueriesToRun; + TSet<ui32> QueriesToSkip; + bool DisableLlvm = false; + bool EnablePushdown = false; + TString ExternalQueries; + TString ExternalQueriesFile; +public: + TString OutFilePath; + ui32 IterationsCount; + TString JsonReportFileName; + + TString GetExternalQueries() const { + TString externalQueries; + if (ExternalQueries) { + externalQueries = ExternalQueries; + } else if (ExternalQueriesFile) { + TFileInput fInput(ExternalQueriesFile); + externalQueries = fInput.ReadAll(); + } + return externalQueries; + } + + TString PatchQuery(const TStringBuf& original) const { + TString result(original.data(), original.size()); + if (EnablePushdown) { + result = "PRAGMA ydb.KqpPushOlapProcess = \"true\";\n" + result; + } + if (DisableLlvm) { + result = "PRAGMA ydb.EnableLlvm=\"false\";\n" + result; + } + return result; + } + + bool NeedRun(const ui32 queryIdx) const { + if (QueriesToRun.size() && !QueriesToRun.contains(queryIdx)) { + return false; + } + if (QueriesToSkip.contains(queryIdx)) { + return false; + } + return true; + } +}; + +class TClickHouseBench { +public: + TClickHouseBench(NYdb::TDriver& driver, const TString& db, const TString& path, const TString& table) + : Driver(driver) + , Database(db) + , Path(path) + , Table(table) + {} + + void Init(); + bool RunBench(IQueryRunner& queryRunner, const TBenchContext& context); + +private: + struct TTestInfo { + TDuration ColdTime; + TDuration Min; + TDuration Max; + double Mean = 0; + double Std = 0; + }; + + static TTestInfo AnalyzeTestRuns(const TVector<TDuration>& timings); + TString FullTablePath() const; + + NYdb::TDriver& Driver; + const TString& Database; + const TString& Path; + const TString& Table; +}; + + +class TClickBenchCommandInit : public NYdb::NConsoleClient::TYdbCommand { +public: + TClickBenchCommandInit(); + void Config(TConfig& config); + int Run(TConfig& config); + +private: + TString Path; + TString Table; +}; + + +class TStreamQueryRunner : public IQueryRunner { +public: + explicit TStreamQueryRunner(NYdb::TDriver& driver) + : SqClient(driver) + {} + TString GetQueries(const TString& fullTablePath, const TString& externalQueries) override; + std::pair<TString, TString> Execute(const TString& query) override; + +private: + std::pair<TString, TString> ResultToYson(NYdb::NTable::TScanQueryPartIterator& it); + +private: + NYdb::NTable::TTableClient SqClient; +}; + +class TClickBenchCommandRun : public NYdb::NConsoleClient::TYdbCommand, public TBenchContext { +public: + TClickBenchCommandRun(); + void Config(TConfig& config); + int Run(TConfig& config); +private: + TString Path; + TString Table; +}; + +class TCommandClickBench : public NYdb::NConsoleClient::TClientCommandTree { +public: + TCommandClickBench() : TClientCommandTree("click_bench") { + AddCommand(std::make_unique<TClickBenchCommandRun>()); + AddCommand(std::make_unique<TClickBenchCommandInit>()); + } +}; + diff --git a/ydb/public/lib/ydb_cli/commands/click_bench_queries.sql b/ydb/public/lib/ydb_cli/commands/click_bench_queries.sql new file mode 100644 index 00000000000..36f4aaa1518 --- /dev/null +++ b/ydb/public/lib/ydb_cli/commands/click_bench_queries.sql @@ -0,0 +1,172 @@ +-- +-- Basic ClickHouse performance test. +-- Queries are adapted from https://github.com/ClickHouse/ClickHouse/blob/master/benchmark/clickhouse/queries.sql +-- +-- NB: click_bench separates queries using simple splitting by semicolon. +-- + +-- q1 +SELECT count(*) FROM {table}; +-- q2 +SELECT count(*) FROM {table} WHERE AdvEngineID != 0; +-- q3 +SELECT sum(AdvEngineID), count(*), avg(ResolutionWidth) FROM {table}; +-- q4 +SELECT sum(UserID) FROM {table}; +-- q5 +SELECT CountDistinctEstimate(UserID) FROM {table}; +-- q6 +SELECT CountDistinctEstimate(SearchPhrase) FROM {table}; +-- q7 +SELECT min(EventDate), max(EventDate) FROM {table}; +-- q8 +SELECT AdvEngineID, count(*) as c FROM {table} WHERE AdvEngineID != 0 GROUP BY AdvEngineID ORDER BY c DESC; +-- q9 +SELECT RegionID, CountDistinctEstimate(UserID) AS u FROM {table} GROUP BY RegionID ORDER BY u DESC LIMIT 10; +-- q10 +SELECT RegionID, sum(AdvEngineID), count(*) AS c, avg(ResolutionWidth), CountDistinctEstimate(UserID) +FROM {table} GROUP BY RegionID ORDER BY c DESC LIMIT 10; +-- q11 +SELECT MobilePhoneModel, CountDistinctEstimate(UserID) AS u +FROM {table} WHERE MobilePhoneModel != '' GROUP BY MobilePhoneModel ORDER BY u DESC LIMIT 10; +-- q12 +SELECT MobilePhone, MobilePhoneModel, CountDistinctEstimate(UserID) AS u +FROM {table} WHERE MobilePhoneModel != '' GROUP BY MobilePhone, MobilePhoneModel ORDER BY u DESC LIMIT 10; +-- q13 +SELECT SearchPhrase, count(*) AS c +FROM {table} WHERE SearchPhrase != '' GROUP BY SearchPhrase ORDER BY c DESC LIMIT 10; +-- q14 +SELECT SearchPhrase, CountDistinctEstimate(UserID) AS u +FROM {table} WHERE SearchPhrase != '' GROUP BY SearchPhrase ORDER BY u DESC LIMIT 10; +-- q15 +SELECT SearchEngineID, SearchPhrase, count(*) AS c +FROM {table} WHERE SearchPhrase != '' GROUP BY SearchEngineID, SearchPhrase ORDER BY c DESC LIMIT 10; +-- q16 +SELECT UserID, count(*) AS c FROM {table} GROUP BY UserID ORDER BY c DESC LIMIT 10; +-- q17 +SELECT UserID, SearchPhrase, count(*) AS c FROM {table} GROUP BY UserID, SearchPhrase ORDER BY c DESC LIMIT 10; +-- q18 +SELECT UserID, SearchPhrase, count(*) AS c FROM {table} GROUP BY UserID, SearchPhrase LIMIT 10; +-- q19 +SELECT UserID, m, SearchPhrase, count(*) AS c +FROM {table} GROUP BY UserID, DateTime::GetMinute(EventTime) AS m, SearchPhrase ORDER BY c DESC LIMIT 10; +-- q20 +SELECT UserID FROM {table} WHERE UserID = 12345678901234567890; +-- q21 +SELECT count(*) FROM {table} WHERE URL LIKE '%metrika%'; +-- q22 +SELECT SearchPhrase, some(URL), count(*) AS c +FROM {table} WHERE URL LIKE '%metrika%' AND SearchPhrase != '' GROUP BY SearchPhrase ORDER BY c DESC LIMIT 10; +-- q23 +SELECT SearchPhrase, some(URL), some(Title), count(*) AS c, CountDistinctEstimate(UserID) +FROM {table} WHERE Title LIKE '%Яндекс%' AND URL NOT LIKE '%.yandex.%' AND SearchPhrase != '' +GROUP BY SearchPhrase ORDER BY c DESC LIMIT 10; +-- q24 +SELECT * FROM {table} WHERE URL LIKE '%metrika%' ORDER BY EventTime LIMIT 10; +-- q25 +SELECT SearchPhrase, EventTime FROM {table} WHERE SearchPhrase != '' ORDER BY EventTime LIMIT 10; +-- q26 +SELECT SearchPhrase FROM {table} WHERE SearchPhrase != '' ORDER BY SearchPhrase LIMIT 10; +-- q27 +SELECT SearchPhrase, EventTime FROM {table} WHERE SearchPhrase != '' ORDER BY EventTime, SearchPhrase LIMIT 10; +-- q28 +SELECT CounterID, avg(length(URL)) AS l, count(*) AS c +FROM {table} WHERE URL != '' GROUP BY CounterID HAVING count(*) > 100000 ORDER BY l DESC LIMIT 25; +-- q29 +SELECT key, avg(length(Referer)) AS l, count(*) AS c, some(Referer) +FROM {table} WHERE Referer != '' GROUP BY Url::CutWWW(Url::GetHost(Referer)) AS key +HAVING count(*) > 100000 ORDER BY l DESC LIMIT 25; +-- q30 +SELECT + sum(ResolutionWidth), sum(ResolutionWidth + 1), sum(ResolutionWidth + 2), sum(ResolutionWidth + 3), + sum(ResolutionWidth + 4), sum(ResolutionWidth + 5), sum(ResolutionWidth + 6), sum(ResolutionWidth + 7), + sum(ResolutionWidth + 8), sum(ResolutionWidth + 9), sum(ResolutionWidth + 10), sum(ResolutionWidth + 11), + sum(ResolutionWidth + 12), sum(ResolutionWidth + 13), sum(ResolutionWidth + 14), sum(ResolutionWidth + 15), + sum(ResolutionWidth + 16), sum(ResolutionWidth + 17), sum(ResolutionWidth + 18), sum(ResolutionWidth + 19), + sum(ResolutionWidth + 20), sum(ResolutionWidth + 21), sum(ResolutionWidth + 22), sum(ResolutionWidth + 23), + sum(ResolutionWidth + 24), sum(ResolutionWidth + 25), sum(ResolutionWidth + 26), sum(ResolutionWidth + 27), + sum(ResolutionWidth + 28), sum(ResolutionWidth + 29), sum(ResolutionWidth + 30), sum(ResolutionWidth + 31), + sum(ResolutionWidth + 32), sum(ResolutionWidth + 33), sum(ResolutionWidth + 34), sum(ResolutionWidth + 35), + sum(ResolutionWidth + 36), sum(ResolutionWidth + 37), sum(ResolutionWidth + 38), sum(ResolutionWidth + 39), + sum(ResolutionWidth + 40), sum(ResolutionWidth + 41), sum(ResolutionWidth + 42), sum(ResolutionWidth + 43), + sum(ResolutionWidth + 44), sum(ResolutionWidth + 45), sum(ResolutionWidth + 46), sum(ResolutionWidth + 47), + sum(ResolutionWidth + 48), sum(ResolutionWidth + 49), sum(ResolutionWidth + 50), sum(ResolutionWidth + 51), + sum(ResolutionWidth + 52), sum(ResolutionWidth + 53), sum(ResolutionWidth + 54), sum(ResolutionWidth + 55), + sum(ResolutionWidth + 56), sum(ResolutionWidth + 57), sum(ResolutionWidth + 58), sum(ResolutionWidth + 59), + sum(ResolutionWidth + 60), sum(ResolutionWidth + 61), sum(ResolutionWidth + 62), sum(ResolutionWidth + 63), + sum(ResolutionWidth + 64), sum(ResolutionWidth + 65), sum(ResolutionWidth + 66), sum(ResolutionWidth + 67), + sum(ResolutionWidth + 68), sum(ResolutionWidth + 69), sum(ResolutionWidth + 70), sum(ResolutionWidth + 71), + sum(ResolutionWidth + 72), sum(ResolutionWidth + 73), sum(ResolutionWidth + 74), sum(ResolutionWidth + 75), + sum(ResolutionWidth + 76), sum(ResolutionWidth + 77), sum(ResolutionWidth + 78), sum(ResolutionWidth + 79), + sum(ResolutionWidth + 80), sum(ResolutionWidth + 81), sum(ResolutionWidth + 82), sum(ResolutionWidth + 83), + sum(ResolutionWidth + 84), sum(ResolutionWidth + 85), sum(ResolutionWidth + 86), sum(ResolutionWidth + 87), + sum(ResolutionWidth + 88), sum(ResolutionWidth + 89) +FROM {table}; +-- q31 +SELECT SearchEngineID, ClientIP, count(*) AS c, sum(Refresh), avg(ResolutionWidth) +FROM {table} WHERE SearchPhrase != '' GROUP BY SearchEngineID, ClientIP ORDER BY c DESC LIMIT 10; +-- q32 +SELECT WatchID, ClientIP, count(*) AS c, sum(Refresh), avg(ResolutionWidth) +FROM {table} WHERE SearchPhrase != '' GROUP BY WatchID, ClientIP ORDER BY c DESC LIMIT 10; +-- q33 +SELECT WatchID, ClientIP, count(*) AS c, sum(Refresh), avg(ResolutionWidth) +FROM {table} GROUP BY WatchID, ClientIP ORDER BY c DESC LIMIT 10; +-- q34 +SELECT URL, count(*) AS c FROM {table} GROUP BY URL ORDER BY c DESC LIMIT 10; +-- q35 +SELECT UserID, URL, count(*) AS c FROM {table} GROUP BY UserID, URL ORDER BY c DESC LIMIT 10; +-- q36 +SELECT x0, x1, x2, x3, count(*) AS c +FROM {table} +GROUP BY ClientIP as x0, ClientIP - 1 as x1, ClientIP - 2 as x2, ClientIP - 3 as x3 ORDER BY c DESC LIMIT 10; +-- q37 +SELECT URL, count(*) AS PageViews +FROM {table} +WHERE + CounterID = 62 AND EventDate >= Date('2013-07-01') AND EventDate <= Date('2013-07-31') AND DontCountHits == 0 + AND Refresh == 0 AND URL != '' +GROUP BY URL ORDER BY PageViews DESC LIMIT 10; +-- q38 +SELECT Title, count(*) AS PageViews +FROM {table} +WHERE + CounterID = 62 AND EventDate >= Date('2013-07-01') AND EventDate <= Date('2013-07-31') AND DontCountHits == 0 AND + Refresh == 0 AND Title != '' +GROUP BY Title ORDER BY PageViews DESC LIMIT 10; +-- q39 +SELECT URL, count(*) AS PageViews +FROM {table} +WHERE + CounterID = 62 AND EventDate >= Date('2013-07-01') AND EventDate <= Date('2013-07-31') AND Refresh == 0 AND + IsLink != 0 AND IsDownload == 0 +GROUP BY URL ORDER BY PageViews DESC LIMIT 1000; +-- q40 +SELECT TraficSourceID, SearchEngineID, AdvEngineID, Src, Dst, count(*) AS PageViews +FROM {table} +WHERE + CounterID = 62 AND EventDate >= Date('2013-07-01') AND EventDate <= Date('2013-07-31') AND Refresh == 0 +GROUP BY + TraficSourceID, SearchEngineID, AdvEngineID, IF(SearchEngineID = 0 AND AdvEngineID = 0, Referer, '') AS Src, + URL AS Dst +ORDER BY PageViews DESC LIMIT 1000; +-- q41 +SELECT URLHash, EventDate, count(*) AS PageViews +FROM {table} +WHERE + CounterID = 62 AND EventDate >= Date('2013-07-01') AND EventDate <= Date('2013-07-31') AND Refresh == 0 AND + TraficSourceID IN (-1, 6) AND RefererHash = Digest::Md5HalfMix('http://example.ru/') +GROUP BY URLHash, EventDate ORDER BY PageViews DESC LIMIT 100; +-- q42 +SELECT WindowClientWidth, WindowClientHeight, count(*) AS PageViews +FROM {table} +WHERE + CounterID = 62 AND EventDate >= Date('2013-07-01') AND EventDate <= Date('2013-07-31') AND Refresh == 0 AND + DontCountHits == 0 AND URLHash = Digest::Md5HalfMix('http://example.ru/') +GROUP BY WindowClientWidth, WindowClientHeight ORDER BY PageViews DESC LIMIT 10000; +-- q43 +SELECT Minute, count(*) AS PageViews +FROM {table} +WHERE + CounterID = 62 AND EventDate >= Date('2013-07-01') AND EventDate <= Date('2013-07-02') AND Refresh == 0 AND + DontCountHits == 0 +GROUP BY DateTime::ToSeconds(EventTime)/60 As Minute ORDER BY Minute diff --git a/ydb/public/lib/ydb_cli/commands/click_bench_schema.sql b/ydb/public/lib/ydb_cli/commands/click_bench_schema.sql new file mode 100644 index 00000000000..30cd0bcbc9f --- /dev/null +++ b/ydb/public/lib/ydb_cli/commands/click_bench_schema.sql @@ -0,0 +1,112 @@ +--!syntax_v1 +CREATE TABLE `{table}` ( + HashUserID Uint64, + CounterID Uint64, + EventDate Date, + AdvEngineID Uint64, + Age Uint64, + BrowserCountry String, + BrowserLanguage String, + CLID Uint64, + ClientEventTime Datetime, + ClientIP Uint64, + ClientTimeZone Int64, + CodeVersion Uint64, + ConnectTiming Uint64, + CookieEnable Uint64, + CounterClass Int64, + DNSTiming Uint64, + DontCountHits Uint64, + EventTime Datetime, + FUniqID Uint64, + FetchTiming Uint64, + FlashMajor Uint64, + FlashMinor Uint64, + FlashMinor2 String, + FromTag String, + GoodEvent Int64, + HID Uint64, + HTTPError Uint64, + HasGCLID Uint64, + HistoryLength Int64, + HitColor String, + IPNetworkID Uint64, + Income Uint64, + Interests Uint64, + IsArtifical Uint64, + IsDownload Uint64, + IsEvent Uint64, + IsLink Uint64, + IsMobile Uint64, + IsNotBounce Uint64, + IsOldCounter Uint64, + IsParameter Uint64, + JavaEnable Uint64, + JavascriptEnable Uint64, + LocalEventTime Datetime, + MobilePhone Uint64, + MobilePhoneModel String, + NetMajor Uint64, + NetMinor Uint64, + OS Uint64, + OpenerName Int64, + OpenstatAdID String, + OpenstatCampaignID String, + OpenstatServiceName String, + OpenstatSourceID String, + OriginalURL String, + PageCharset String, + ParamCurrency String, + ParamCurrencyID Uint64, + ParamOrderID String, + ParamPrice Int64, + Params String, + Referer String, + RefererCategoryID Uint64, + RefererHash Uint64, + RefererRegionID Uint64, + Refresh Uint64, + RegionID Uint64, + RemoteIP Uint64, + ResolutionDepth Uint64, + ResolutionHeight Uint64, + ResolutionWidth Uint64, + ResponseEndTiming Uint64, + ResponseStartTiming Uint64, + Robotness Uint64, + SearchEngineID Uint64, + SearchPhrase String, + SendTiming Uint64, + Sex Uint64, + SilverlightVersion1 Uint64, + SilverlightVersion2 Uint64, + SilverlightVersion3 Uint64, + SilverlightVersion4 Uint64, + SocialAction String, + SocialNetwork String, + SocialSourceNetworkID Uint64, + SocialSourcePage String, + Title String, + TraficSourceID Int64, + URL String, + URLCategoryID Uint64, + URLHash Uint64, + URLRegionID Uint64, + UTMCampaign String, + UTMContent String, + UTMMedium String, + UTMSource String, + UTMTerm String, + UserAgent Uint64, + UserAgentMajor Uint64, + UserAgentMinor String, + UserID Uint64, + WatchID Uint64, + WindowClientHeight Uint64, + WindowClientWidth Uint64, + WindowName Int64, + WithHash Uint64, + PRIMARY KEY (CounterID, EventDate, UserID, WatchID, ClientEventTime, LocalEventTime, EventTime, ClientIP, ConnectTiming, HistoryLength) +) WITH ( + AUTO_PARTITIONING_BY_SIZE = ENABLED +); diff --git a/ydb/public/lib/ydb_cli/commands/stock_workload.h b/ydb/public/lib/ydb_cli/commands/stock_workload.h index c2e12fb7cc9..8ed4317a7f7 100644 --- a/ydb/public/lib/ydb_cli/commands/stock_workload.h +++ b/ydb/public/lib/ydb_cli/commands/stock_workload.h @@ -95,4 +95,4 @@ private: }; } -}
\ No newline at end of file +} diff --git a/ydb/public/lib/ydb_cli/commands/ydb_workload.cpp b/ydb/public/lib/ydb_cli/commands/ydb_workload.cpp index 559fe8171ef..1f9a5bf85b7 100644 --- a/ydb/public/lib/ydb_cli/commands/ydb_workload.cpp +++ b/ydb/public/lib/ydb_cli/commands/ydb_workload.cpp @@ -2,6 +2,7 @@ #include "stock_workload.h" #include "kv_workload.h" +#include "click_bench.h" #include <ydb/library/workload/workload_factory.h> #include <ydb/public/lib/ydb_cli/commands/ydb_common.h> @@ -36,6 +37,7 @@ TCommandWorkload::TCommandWorkload() { AddCommand(std::make_unique<TCommandStock>()); AddCommand(std::make_unique<TCommandKv>()); +// AddCommand(std::make_unique<TCommandClickBench>()); } TWorkloadCommand::TWorkloadCommand(const TString& name, const std::initializer_list<TString>& aliases, const TString& description) |