mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-04 08:09:27 +00:00
185 lines
6.4 KiB
HTML
185 lines
6.4 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>GROUP BY Benchmark - Performance Chart</title>
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
|
|
<style>
|
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; margin: 0; padding: 20px; background: #f5f7fa; }
|
|
h1 { text-align: center; color: #333; margin-bottom: 5px; }
|
|
.subtitle { text-align: center; color: #666; margin-bottom: 30px; font-size: 14px; }
|
|
.chart-container { background: white; border-radius: 12px; padding: 24px; margin: 0 auto 30px; max-width: 1100px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
|
.chart-container h2 { margin-top: 0; color: #444; font-size: 16px; }
|
|
canvas { width: 100% !important; }
|
|
.summary { background: white; border-radius: 12px; padding: 24px; margin: 0 auto; max-width: 1100px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
|
.summary table { width: 100%; border-collapse: collapse; font-size: 14px; }
|
|
.summary th, .summary td { padding: 10px 12px; text-align: left; border-bottom: 1px solid #eee; }
|
|
.summary th { background: #f8f9fa; font-weight: 600; color: #555; }
|
|
.summary tr:hover { background: #f0f7ff; }
|
|
.tag { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 12px; font-weight: 500; }
|
|
.tag-1f { background: #e3f2fd; color: #1565c0; }
|
|
.tag-2f { background: #fff3e0; color: #e65100; }
|
|
.tag-bl { background: #f3e5f5; color: #7b1fa2; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<h1>GROUP BY Performance Benchmark</h1>
|
|
<div class="subtitle">10,000,000 records · 5 rounds per query · OpenObserve + Tantivy</div>
|
|
|
|
<div class="chart-container">
|
|
<h2>Latency per Round (all queries)</h2>
|
|
<canvas id="lineChart" height="100"></canvas>
|
|
</div>
|
|
|
|
<div class="chart-container">
|
|
<h2>Median Latency Comparison</h2>
|
|
<canvas id="barChart" height="60"></canvas>
|
|
</div>
|
|
|
|
<div class="summary">
|
|
<h2 style="margin-top:0; color:#444;">Summary Table</h2>
|
|
<table id="summaryTable">
|
|
<thead>
|
|
<tr><th>Query</th><th>Type</th><th>Min</th><th>Median</th><th>Mean</th><th>Max</th><th>StdDev</th></tr>
|
|
</thead>
|
|
<tbody></tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<script>
|
|
const data = {
|
|
"1-field GROUP BY (userid, LIMIT 10)": {
|
|
"latencies": [130.56, 82.82, 88.39, 89.55, 83.41],
|
|
"min": 82.82, "max": 130.56, "mean": 94.95, "median": 88.39, "stdev": 20.13
|
|
},
|
|
"1-field GROUP BY (searchphrase, LIMIT 10)": {
|
|
"latencies": [161.52, 79.49, 84.71, 84.64, 87.53],
|
|
"min": 79.49, "max": 161.52, "mean": 99.58, "median": 84.71, "stdev": 34.75
|
|
},
|
|
"1-field GROUP BY (service, LIMIT 20)": {
|
|
"latencies": [151.94, 80.97, 85.08, 85.87, 78.16],
|
|
"min": 78.16, "max": 151.94, "mean": 96.40, "median": 85.08, "stdev": 31.20
|
|
},
|
|
"2-field GROUP BY (userid+searchphrase, LIMIT 10)": {
|
|
"latencies": [188.55, 153.51, 152.81, 148.32, 145.67],
|
|
"min": 145.67, "max": 188.55, "mean": 157.77, "median": 152.81, "stdev": 17.51
|
|
},
|
|
"2-field GROUP BY (userid+service, LIMIT 10)": {
|
|
"latencies": [159.39, 108.85, 105.67, 110.62, 103.72],
|
|
"min": 103.72, "max": 159.39, "mean": 117.65, "median": 108.85, "stdev": 23.49
|
|
},
|
|
"2-field GROUP BY (service+method, LIMIT 20)": {
|
|
"latencies": [152.64, 87.91, 97.47, 93.10, 96.85],
|
|
"min": 87.91, "max": 152.64, "mean": 105.59, "median": 96.85, "stdev": 26.57
|
|
},
|
|
"Baseline: full-scan (non-indexed)": {
|
|
"latencies": [158.97, 121.34, 115.34, 111.15, 106.62],
|
|
"min": 106.62, "max": 158.97, "mean": 122.68, "median": 115.34, "stdev": 21.00
|
|
}
|
|
};
|
|
|
|
const colors = {
|
|
'1-field': ['#1976D2', '#42A5F5', '#90CAF9'],
|
|
'2-field': ['#E65100', '#FF9800', '#FFCC80'],
|
|
'Baseline': ['#7B1FA2']
|
|
};
|
|
|
|
const labels = ['Round 1', 'Round 2', 'Round 3', 'Round 4', 'Round 5'];
|
|
const datasets = [];
|
|
let colorIdx1 = 0, colorIdx2 = 0;
|
|
|
|
Object.entries(data).forEach(([key, val]) => {
|
|
let color, dash;
|
|
if (key.startsWith('1-field')) {
|
|
color = colors['1-field'][colorIdx1++];
|
|
dash = [];
|
|
} else if (key.startsWith('2-field')) {
|
|
color = colors['2-field'][colorIdx2++];
|
|
dash = [5, 5];
|
|
} else {
|
|
color = colors['Baseline'][0];
|
|
dash = [10, 5];
|
|
}
|
|
datasets.push({
|
|
label: key,
|
|
data: val.latencies,
|
|
borderColor: color,
|
|
backgroundColor: color + '20',
|
|
borderWidth: 2.5,
|
|
borderDash: dash,
|
|
pointRadius: 4,
|
|
pointHoverRadius: 6,
|
|
tension: 0.3,
|
|
fill: false
|
|
});
|
|
});
|
|
|
|
// Line chart
|
|
new Chart(document.getElementById('lineChart'), {
|
|
type: 'line',
|
|
data: { labels, datasets },
|
|
options: {
|
|
responsive: true,
|
|
plugins: {
|
|
legend: { position: 'bottom', labels: { usePointStyle: true, padding: 15 } },
|
|
tooltip: { callbacks: { label: ctx => `${ctx.dataset.label}: ${ctx.parsed.y.toFixed(1)} ms` } }
|
|
},
|
|
scales: {
|
|
y: { title: { display: true, text: 'Latency (ms)' }, beginAtZero: false },
|
|
x: { title: { display: true, text: 'Round' } }
|
|
}
|
|
}
|
|
});
|
|
|
|
// Bar chart - median comparison
|
|
const barLabels = Object.keys(data);
|
|
const barValues = Object.values(data).map(v => v.median);
|
|
const barColors = barLabels.map(l => {
|
|
if (l.startsWith('1-field')) return '#1976D2';
|
|
if (l.startsWith('2-field')) return '#E65100';
|
|
return '#7B1FA2';
|
|
});
|
|
|
|
new Chart(document.getElementById('barChart'), {
|
|
type: 'bar',
|
|
data: {
|
|
labels: barLabels.map(l => l.replace('GROUP BY ', '').replace('Baseline: full-scan (non-indexed)', 'Baseline (full-scan)')),
|
|
datasets: [{
|
|
label: 'Median Latency (ms)',
|
|
data: barValues,
|
|
backgroundColor: barColors.map(c => c + 'CC'),
|
|
borderColor: barColors,
|
|
borderWidth: 1.5,
|
|
borderRadius: 6
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
plugins: {
|
|
legend: { display: false },
|
|
tooltip: { callbacks: { label: ctx => `${ctx.parsed.y.toFixed(1)} ms` } }
|
|
},
|
|
scales: {
|
|
y: { title: { display: true, text: 'Median Latency (ms)' }, beginAtZero: true },
|
|
x: { ticks: { maxRotation: 20 } }
|
|
}
|
|
}
|
|
});
|
|
|
|
// Summary table
|
|
const tbody = document.querySelector('#summaryTable tbody');
|
|
Object.entries(data).forEach(([key, val]) => {
|
|
const type = key.startsWith('1-field') ? '<span class="tag tag-1f">1-field</span>' :
|
|
key.startsWith('2-field') ? '<span class="tag tag-2f">2-field</span>' :
|
|
'<span class="tag tag-bl">Baseline</span>';
|
|
tbody.innerHTML += `<tr>
|
|
<td>${key}</td><td>${type}</td>
|
|
<td>${val.min.toFixed(1)} ms</td><td><strong>${val.median.toFixed(1)} ms</strong></td>
|
|
<td>${val.mean.toFixed(1)} ms</td><td>${val.max.toFixed(1)} ms</td><td>${val.stdev.toFixed(1)} ms</td>
|
|
</tr>`;
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|