3. SQL 基础回顾(一):SELECT 查询、WHERE 条件过滤、ORDER BY 排序、LIMIT 分页、DISTINCT 去重
在构建实时监控大屏时,后端数据集成层最核心的任务是从数据库中高效、准确地提取 KPI 指标数据。SQL 的 数据查询语言(DQL) 是完成这一任务的基础工具。本节将系统回顾 SELECT 查询、WHERE 条件过滤、ORDER BY 排序、LIMIT 分页以及 DISTINCT 去重五个核心子句,为后续的复杂查询与数据集成打下坚实基础。
3.1 SELECT 查询:数据检索的起点
SELECT 语句用于从一个或多个表中检索数据行。其基本语法结构如下:
SELECT column1, column2, ...
FROM table_name
[WHERE condition]
[ORDER BY column1 [ASC|DESC]]
[LIMIT [offset,] row_count]
[DISTINCT];
在监控大屏场景中,我们通常需要从 monitor_metrics(监控指标表)或 kpi_records(KPI 记录表)中提取数据。以下是一个基础查询示例:
-- 查询所有监控指标的名称和当前值
SELECT metric_name, current_value
FROM monitor_metrics;
SELECT *,而是明确列出需要的列名。这可以减少网络传输的数据量,并提升查询解析效率。
3.2 WHERE 条件过滤:精准定位目标数据
WHERE 子句用于从表中筛选出满足特定条件的行。在实时监控中,我们经常需要根据时间范围、指标类型、阈值状态等条件进行过滤。
常用过滤条件对比表:
| 运算符 | 说明 | 监控大屏应用示例 |
|---|---|---|
= |
等于 | WHERE metric_type = 'CPU' |
> / < / >= / <= |
比较运算符 | WHERE current_value > 90(告警阈值) |
BETWEEN ... AND ... |
范围匹配 | WHERE record_time BETWEEN '2025-01-01 00:00:00' AND '2025-01-01 23:59:59' |
IN (...) |
集合匹配 | WHERE server_id IN ('SVR001', 'SVR002', 'SVR003') |
LIKE |
模糊匹配 | WHERE metric_name LIKE 'disk_%' |
AND / OR |
逻辑组合 | WHERE status = 'ERROR' AND severity >= 3 |
实战案例: 查询 CPU 使用率超过 85% 且发生在最近 1 小时内的告警记录。
SELECT server_id, metric_name, current_value, record_time
FROM kpi_records
WHERE metric_name = 'cpu_usage'
AND current_value > 85
AND record_time >= NOW() - INTERVAL 1 HOUR;
WHERE DATE(record_time) = '2025-01-01')会导致索引失效。应尽量使用范围查询(BETWEEN 或 >= / <)来保持查询性能。
3.3 ORDER BY 排序:让数据有序呈现
ORDER BY 子句用于对查询结果集按照一个或多个列进行排序。在监控大屏中,排序常用于展示 Top-N 指标、按时间倒序显示最新数据等场景。
- ASC:升序排序(默认),如按时间从早到晚。
- DESC:降序排序,如按指标值从高到低。
- 多列排序:先按第一列排序,相同值再按第二列排序。
-- 按 CPU 使用率降序排列,显示前 10 个最繁忙的服务器
SELECT server_id, cpu_usage, memory_usage, record_time
FROM server_metrics
ORDER BY cpu_usage DESC, memory_usage DESC
LIMIT 10;
record_time)建立索引。
3.4 LIMIT 分页:控制数据输出量
LIMIT 子句用于限制查询返回的行数,是实现分页查询的核心工具。其语法有两种常见形式:
| 语法形式 | 说明 | 示例 |
|---|---|---|
LIMIT row_count |
返回前 row_count 行 | LIMIT 20(返回前 20 行) |
LIMIT offset, row_count |
跳过 offset 行,返回后续 row_count 行 | LIMIT 40, 20(返回第 41~60 行) |
分页查询实战: 在监控大屏的历史数据回溯页面,通常需要分页加载数据。
-- 查询第 3 页数据,每页显示 20 条记录
SELECT id, metric_name, current_value, record_time
FROM kpi_records
WHERE metric_type = 'NETWORK'
ORDER BY record_time DESC
LIMIT 40, 20; -- 跳过前 40 条,取接下来的 20 条
LIMIT 100000, 20),数据库仍需扫描大量行。优化方案是使用“游标分页”或“键集分页”,即基于上一页最后一条记录的 ID 或时间戳进行过滤,而非使用 offset。
3.5 DISTINCT 去重:消除重复数据
DISTINCT 关键字用于从查询结果中去除重复的行,返回唯一不同的值。在监控大屏中,常用于获取不重复的指标类型列表、服务器列表或状态枚举值。
-- 获取所有不重复的监控指标类型
SELECT DISTINCT metric_type
FROM monitor_metrics;
-- 获取所有发生过告警的不重复服务器 ID
SELECT DISTINCT server_id
FROM alert_records
WHERE alert_status = 'ACTIVE';
EXISTS 或 GROUP BY 配合 HAVING COUNT(*) = 1 来替代。
3.6 综合实战:监控大屏 Top-N 指标查询
将上述子句组合使用,可以构建一个典型的监控大屏数据查询:获取当前 CPU 使用率最高的 5 台服务器,且只显示不同的服务器 ID。
SELECT DISTINCT server_id, cpu_usage, record_time
FROM server_metrics
WHERE metric_type = 'CPU'
AND record_time >= NOW() - INTERVAL 5 MINUTE
ORDER BY cpu_usage DESC
LIMIT 5;
该查询的执行逻辑顺序为:FROM → WHERE → SELECT (含 DISTINCT) → ORDER BY → LIMIT。理解这一顺序对于编写正确且高效的 SQL 至关重要。
3.7 SQL 查询执行流程与子句逻辑关系
下图展示了 SELECT 查询中各子句的逻辑执行顺序与数据流向,帮助理解 SQL 引擎如何处理一条完整的查询语句。
3.8 本章知识点速查表
| 子句/关键字 | 核心作用 | 监控大屏典型场景 | 性能关注点 |
|---|---|---|---|
| SELECT | 指定要检索的列 | 提取 KPI 指标名称与值 | 避免 SELECT * |
| WHERE | 行级条件过滤 | 按时间范围、阈值过滤告警 | 索引列避免函数包裹 |
| ORDER BY | 结果集排序 | Top-N 指标、时间倒序 | 利用索引避免文件排序 |
| LIMIT | 限制返回行数 | 分页加载历史数据 | 大 offset 时使用游标分页 |
| DISTINCT | 去除重复行 | 获取不重复的服务器/指标类型 | 大数据量时考虑 GROUP BY |
api_latency_log 表,包含 api_name、latency_ms、call_time 三个字段。请编写一条 SQL 查询,获取今天延迟最高的 10 个不同 API 名称及其对应的最大延迟值,并按延迟降序排列。