From 32d28c03846a44ac0bcf399c15910969b082165e Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 9 Mar 2012 04:45:27 +0000 Subject: [PATCH] dbms: development [#CONV-2944]. --- .../DB/DataStreams/IBlockInputStream.h | 6 ++++ dbms/src/DataStreams/IBlockInputStream.cpp | 22 ++++++++++++++ dbms/src/Server/Handler.cpp | 30 +++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/dbms/include/DB/DataStreams/IBlockInputStream.h b/dbms/include/DB/DataStreams/IBlockInputStream.h index 09f5f9cce98..3e76ea4a967 100644 --- a/dbms/include/DB/DataStreams/IBlockInputStream.h +++ b/dbms/include/DB/DataStreams/IBlockInputStream.h @@ -48,8 +48,14 @@ public: void dumpTree(std::ostream & ostr, size_t indent = 0); void dumpTreeWithProfile(std::ostream & ostr, size_t indent = 0); + /// Получить листовые источники (не считая этот). + BlockInputStreams getLeaves(); + protected: BlockInputStreams children; + +private: + void getLeavesImpl(BlockInputStreams & res, BlockInputStreamPtr this_shared_ptr = NULL); }; diff --git a/dbms/src/DataStreams/IBlockInputStream.cpp b/dbms/src/DataStreams/IBlockInputStream.cpp index dd72204dfe1..525f3f48600 100644 --- a/dbms/src/DataStreams/IBlockInputStream.cpp +++ b/dbms/src/DataStreams/IBlockInputStream.cpp @@ -50,5 +50,27 @@ String IBlockInputStream::getShortName() const return res; } + +BlockInputStreams IBlockInputStream::getLeaves() +{ + BlockInputStreams res; + getLeavesImpl(res); + return res; +} + + +void IBlockInputStream::getLeavesImpl(BlockInputStreams & res, BlockInputStreamPtr this_shared_ptr) +{ + if (children.empty()) + { + if (this_shared_ptr) + res.push_back(this_shared_ptr); + } + else + for (BlockInputStreams::iterator it = children.begin(); it != children.end(); ++it) + (*it)->getLeavesImpl(res, *it); +} + + } diff --git a/dbms/src/Server/Handler.cpp b/dbms/src/Server/Handler.cpp index ca325beea57..cd96f22e3cf 100644 --- a/dbms/src/Server/Handler.cpp +++ b/dbms/src/Server/Handler.cpp @@ -1,6 +1,10 @@ +#include + #include #include +#include + #include #include @@ -8,6 +12,8 @@ #include #include +#include + #include #include "Handler.h" @@ -45,7 +51,9 @@ void HTTPRequestHandler::processQuery(Poco::Net::NameValueCollection & params, s if (params.has("max_threads")) context.settings.max_threads = Poco::NumberParser::parseUnsigned(params.get("max_threads")); + Stopwatch watch; executeQuery(in, out, context, query_plan); + watch.stop(); if (query_plan) { @@ -53,6 +61,28 @@ void HTTPRequestHandler::processQuery(Poco::Net::NameValueCollection & params, s log_str << "Query plan:\n"; query_plan->dumpTree(log_str); LOG_DEBUG(log, log_str.str()); + + /// Выведем информацию о том, сколько считано строк и байт. + BlockInputStreams leaves = query_plan->getLeaves(); + size_t rows = 0; + size_t bytes = 0; + + for (BlockInputStreams::const_iterator it = leaves.begin(); it != leaves.end(); ++it) + { + if (const IProfilingBlockInputStream * profiling = dynamic_cast(&**it)) + { + const BlockStreamProfileInfo & info = profiling->getInfo(); + rows += info.rows; + bytes += info.bytes; + } + } + + if (rows != 0) + { + LOG_INFO(log, std::fixed << std::setprecision(3) + << "Read " << rows << " rows, " << bytes / 1048576.0 << " MB in " << watch.elapsedSeconds() << " sec., " + << static_cast(rows / watch.elapsedSeconds()) << " rows/sec., " << bytes / 1048576.0 / watch.elapsedSeconds() << " MB/sec."); + } } }