summaryrefslogtreecommitdiff
path: root/src/mongo/db/exec
diff options
context:
space:
mode:
authorAdityavardhan Agrawal <adi.agrawal@mongodb.com>2023-03-02 14:53:37 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-03-02 18:50:01 +0000
commit4f495faecc431ea8635eb5d773c3f3cf5fb4c938 (patch)
tree419dd4b6227422161c6fe8582305790405a0c93b /src/mongo/db/exec
parent07cced070b8b2f4e6d2704060138c56ca238239d (diff)
downloadmongo-4f495faecc431ea8635eb5d773c3f3cf5fb4c938.tar.gz
SERVER-70727 Add sort spill stats to explain
Diffstat (limited to 'src/mongo/db/exec')
-rw-r--r--src/mongo/db/exec/plan_stats.h3
-rw-r--r--src/mongo/db/exec/sbe/stages/sort.cpp9
-rw-r--r--src/mongo/db/exec/sbe/stages/sort.h3
-rw-r--r--src/mongo/db/exec/sort_executor.h20
4 files changed, 35 insertions, 0 deletions
diff --git a/src/mongo/db/exec/plan_stats.h b/src/mongo/db/exec/plan_stats.h
index de30eef1a55..a1715e00db7 100644
--- a/src/mongo/db/exec/plan_stats.h
+++ b/src/mongo/db/exec/plan_stats.h
@@ -792,6 +792,9 @@ struct SortStats : public SpecificStats {
// The number of times that we spilled data to disk during the execution of this query.
uint64_t spills = 0u;
+
+ // The maximum size of the spill file written to disk, or 0 if no spilling occurred.
+ uint64_t spilledDataStorageSize = 0u;
};
struct MergeSortStats : public SpecificStats {
diff --git a/src/mongo/db/exec/sbe/stages/sort.cpp b/src/mongo/db/exec/sbe/stages/sort.cpp
index 61c67d4ed79..05840435a82 100644
--- a/src/mongo/db/exec/sbe/stages/sort.cpp
+++ b/src/mongo/db/exec/sbe/stages/sort.cpp
@@ -167,6 +167,8 @@ std::unique_ptr<PlanStageStats> SortStage::getStats(bool includeDebugInfo) const
static_cast<long long>(_specificStats.totalDataSizeBytes));
bob.appendBool("usedDisk", _specificStats.spills > 0);
bob.appendNumber("spills", static_cast<long long>(_specificStats.spills));
+ bob.appendNumber("spilledDataStorageSize",
+ static_cast<long long>(_specificStats.spilledDataStorageSize));
BSONObjBuilder childrenBob(bob.subobjStart("orderBySlots"));
for (size_t idx = 0; idx < _obs.size(); ++idx) {
@@ -294,6 +296,10 @@ void SortStage::SortImpl<KeyRow, ValueRow>::makeSorter() {
? _stage._specificStats.limit
: 0;
opts.moveSortedDataIntoIterator = true;
+ if (_stage._allowDiskUse) {
+ _stage._sorterFileStats = std::make_unique<SorterFileStats>(nullptr);
+ opts.sorterFileStats = _stage._sorterFileStats.get();
+ }
auto comp = [&](const KeyRow& lhs, const KeyRow& rhs) {
auto size = lhs.size();
@@ -365,6 +371,9 @@ void SortStage::SortImpl<KeyRow, ValueRow>::open(bool reOpen) {
_mergeIt.reset(_sorter->done());
_stage._specificStats.spills += _sorter->stats().spilledRanges();
_stage._specificStats.keysSorted += _sorter->stats().numSorted();
+ if (_stage._sorterFileStats) {
+ _stage._specificStats.spilledDataStorageSize += _stage._sorterFileStats->bytesSpilled();
+ }
auto& metricsCollector = ResourceConsumption::MetricsCollector::get(_stage._opCtx);
metricsCollector.incrementKeysSorted(_sorter->stats().numSorted());
metricsCollector.incrementSorterSpills(_sorter->stats().spilledRanges());
diff --git a/src/mongo/db/exec/sbe/stages/sort.h b/src/mongo/db/exec/sbe/stages/sort.h
index 61ca202536e..1b4dd9ea7ed 100644
--- a/src/mongo/db/exec/sbe/stages/sort.h
+++ b/src/mongo/db/exec/sbe/stages/sort.h
@@ -30,6 +30,7 @@
#pragma once
#include "mongo/db/exec/sbe/stages/stages.h"
+#include "mongo/db/sorter/sorter_stats.h"
namespace mongo {
template <typename Key, typename Value>
@@ -150,6 +151,8 @@ private:
const value::SlotVector _vals;
const bool _allowDiskUse;
+ std::unique_ptr<SorterFileStats> _sorterFileStats;
+
std::unique_ptr<SortIface> _stageImpl;
SortStats _specificStats;
diff --git a/src/mongo/db/exec/sort_executor.h b/src/mongo/db/exec/sort_executor.h
index 6e1a9d06d45..5ff1ba8bfff 100644
--- a/src/mongo/db/exec/sort_executor.h
+++ b/src/mongo/db/exec/sort_executor.h
@@ -78,6 +78,9 @@ public:
_sortPattern.serialize(SortPattern::SortKeySerialization::kForExplain).toBson();
_stats.limit = limit;
_stats.maxMemoryUsageBytes = maxMemoryUsageBytes;
+ if (allowDiskUse) {
+ _sorterFileStats = std::make_unique<SorterFileStats>(nullptr);
+ }
}
const SortPattern& sortPattern() const {
@@ -117,6 +120,20 @@ public:
return _stats;
}
+ SorterFileStats* getSorterFileStats() const {
+ if (!_sorterFileStats) {
+ return nullptr;
+ }
+ return _sorterFileStats.get();
+ }
+
+ long long spilledDataStorageSize() const {
+ if (!_sorterFileStats) {
+ return 0;
+ }
+ return _sorterFileStats->bytesSpilled();
+ }
+
/**
* Add data item to be sorted of type T with sort key specified by Value to the sort executor.
* Should only be called before 'loadingDone()' is called.
@@ -140,6 +157,7 @@ public:
_stats.keysSorted += _sorter->stats().numSorted();
_stats.spills += _sorter->stats().spilledRanges();
_stats.totalDataSizeBytes += _sorter->stats().bytesSorted();
+ _stats.spilledDataStorageSize += spilledDataStorageSize();
_sorter.reset();
}
@@ -185,6 +203,7 @@ private:
if (_diskUseAllowed) {
opts.extSortAllowed = true;
opts.tempDir = _tempDir;
+ opts.sorterFileStats = _sorterFileStats.get();
}
return opts;
@@ -194,6 +213,7 @@ private:
const std::string _tempDir;
const bool _diskUseAllowed;
+ std::unique_ptr<SorterFileStats> _sorterFileStats;
std::unique_ptr<DocumentSorter> _sorter;
std::unique_ptr<typename DocumentSorter::Iterator> _output;