上一篇 下一篇 分享链接 返回 返回顶部

双960G NVMe SSD RAID0香港服务器数据库全量查询速度怎么测?

发布人:Minchunlin 发布时间:2026-10-04 23:20 阅读量:2

把双960G NVMe SSD组成RAID0,并不意味着数据库全量查询时间一定缩短一半。数据库查询速度由数据是否在内存、实际执行计划、CPU计算量、临时排序、并发排队以及结果传输共同决定,磁盘顺序读取速度只是其中一个环节。

要测双960G NVMe SSD RAID0香港服务器的数据库全量查询速度,应至少拆成两类测试:一类是只返回少量结果、重点观察数据库扫描和计算能力;另一类是返回完整结果集,观察磁盘读取、数据库处理、网络传输和客户端写入的端到端耗时。每类测试都要分别记录单并发与多并发、冷缓存与热缓存,不能只执行一次 SELECT 后用一个秒数下结论。

一、先定义“全量查询速度”究竟在测什么

“数据库全量查询”可能指完全扫描一张表,也可能指查询整个业务库、导出全部行,或者对大表执行聚合、排序和关联。不同定义对应的瓶颈不同。

例如:

  • COUNT(*)、SUM() 这类只返回一行的查询,主要衡量扫描、解析、聚合和计算速度;
  • SELECT * 返回数千万行时,除了数据库读取,还会受到结果编码、网络发送、客户端接收和文件写入影响;
  • GROUP BY、ORDER BY、多表 JOIN 可能产生临时表、哈希表或磁盘临时文件,速度不再等同于NVMe顺序读取速度;
  • 使用索引覆盖的查询可能没有读取完整数据页,即使SQL看起来查询了整张表,也未必是真正的全表扫描。

因此,测试前应先写清楚测试对象:

测试对象主要回答的问题不宜直接代表的场景
全表扫描后返回聚合值数据库读取和计算能力如何完整结果集导出速度
全表扫描后返回部分列扫描数据量和编码开销如何复杂关联查询
全量结果集返回客户端端到端读取、传输、客户端处理速度纯磁盘性能
全表扫描并排序或分组CPU、临时空间和内存压力如何简单顺序扫描
多个全量查询同时执行并发下的吞吐和尾延迟如何单个查询的最低延迟

适合做基础基准的查询,应返回一个较小结果集,避免网络传输成为主要变量。例如可以使用业务测试库中的事实表和数值列:

SELECT
    COUNT(*) AS row_count,
    SUM(metric_col) AS metric_sum
FROM fact_table;

这里的 fact_table 和 metric_col 只是示例,应替换为测试库中的实际对象。执行后必须查看实际执行计划,确认数据库确实读取了目标数据范围,而不是直接使用一个很小的索引或缓存结果。

如果要测完整结果集,则应单独记录“从发出查询到客户端收到最后一行”的时间,同时记录返回行数和结果集大小。这个结果代表业务端体验,但不能直接当作RAID0的磁盘读取速度。

二、需要记录的指标及其含义

1. 完成时间与延迟分布

单次全量查询最直观的指标是完成时间,也就是从查询发出到最后一个结果返回的墙钟时间。对于只返回聚合值的查询,完成时间基本接近数据库内部执行时间;对于返回大量数据的查询,完成时间还包括数据传输和客户端消费时间。

不要只记录平均值,至少应保存:

  • 最小值:显示理想状态下的最快完成时间;
  • 中位数,也就是P50:反映常态体验;
  • P95:表示较慢的5%请求;
  • P99:观察并发排队、缓存抖动和临时I/O造成的尾延迟;
  • 超时、连接失败、返回错误和被取消的请求数。

全量查询通常耗时较长,单次运行只能说明一个样本。若要讨论P95或P99,建议每个测试点至少有30个有效样本;如果查询本身需要数分钟,无法执行足够样本,就应直接报告样本数,不要把少量样本计算出的P95描述成稳定结论。

2. 扫描吞吐量与返回吞吐量

扫描吞吐量用于回答“数据库每秒处理了多少数据”,计算方式是:

扫描吞吐量 = 实际扫描数据量 ÷ 查询完成时间

例如,执行计划和监控显示实际读取了240 GB,耗时96秒:

  • 240 GB ÷ 96秒 = 2.5 GB/s;
  • 按十进制单位换算,240 GB × 1000 MB/GB ÷ 96秒 = 2500 MB/s。

这个数值表示数据库读取路径的平均处理速率,不等于NVMe设备的规格速度,也不等于查询结果向客户端发送的速率。

如果返回结果集大小为80 GB,客户端从发出请求到接收完成耗时100秒,则结果传输速率为:

  • 80 GB × 8 × 1000 ÷ 100秒 = 6400 Mbps。

这里的计算使用十进制GB和Mbps。若监控工具显示的是GiB、MiB,应先统一单位,否则容易把磁盘读取速度和网络传输速度混在一起。

3. 吞吐量、并发数与排队

单并发测试适合观察单条查询的基础能力,多并发测试则用于判断服务器是否能同时处理多条全量查询。

建议逐级测试以下并发数:

  • 并发1:观察单条查询基线;
  • 并发2或4:观察多个查询是否能够利用双盘并行能力;
  • 并发8或更高:观察CPU、内存、I/O队列和临时空间是否出现争用;
  • 业务实际并发:验证真实工作负载下的响应和吞吐。

在多并发场景中,同时记录:

  • 每秒完成的查询数;
  • 每条查询的P50、P95和P99;
  • 总扫描量和总读取吞吐量;
  • 等待时间、超时数和错误数;
  • 单个查询是否因为其他查询而显著变慢。

如果并发从1增加到4后,总吞吐量提高,但P95急剧上升,说明系统获得了更多总体处理量,却已经接近某个资源的饱和点。对于后台报表,这种取舍可能可以接受;对于有明确响应时间要求的在线查询,则不能只看总吞吐量。

4. CPU、内存和I/O指标

数据库全量查询的耗时必须与资源监控放在同一时间轴上观察。

指标需要观察的内容常见判断
CPU用户态占用SQL计算、聚合、排序、表达式处理高占用且磁盘等待低,可能是CPU受限
CPU系统态占用内核I/O、网络、文件系统处理过高时可能存在I/O或系统调用压力
iowaitCPU等待磁盘完成的时间较高且磁盘延迟上升,可能是存储受限
内存使用量数据库缓存、排序区、连接和临时结构内存不足时可能触发回收或交换
Swap活动是否发生内存换出全量查询期间出现Swap会明显干扰结果
磁盘带宽每秒读取多少数据判断是否接近持续读取能力
IOPS和队列深度I/O请求数量和等待情况判断随机访问、并发排队和设备饱和
I/O等待时间单次I/O平均完成时间并发增加后明显上升,说明争用加剧
文件系统临时空间排序、哈希、临时表是否落盘临时文件增长会改变测试结论
网络发送速率结果集返回到客户端的速度判断端到端查询是否被传输限制

在Linux服务器上,可以在测试窗口同步采集基础信息:

date
uname -a
lscpu
free -h
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS
cat /proc/mdstat
vmstat 1
iostat -xm 1

cat /proc/mdstat主要适用于查看Linux软件RAID状态;如果服务器使用其他形式的阵列管理,应使用对应管理工具确认阵列是否处于正常状态。iostat通常由sysstat软件包提供,如果命令不存在,应先确认系统工具是否已安装,不要因为工具缺失而随意更改生产环境。

三、测试前必须固定的变量

1. 固定数据集和数据库状态

至少记录以下信息:

  • 数据库类型和版本;
  • 操作系统、内核和文件系统;
  • 数据表总行数;
  • 表数据大小、索引大小和实际扫描大小;
  • 数据库缓存或缓冲池大小;
  • 测试数据是否大于可用内存;
  • 查询连接方式;
  • 客户端与数据库是否在同一台服务器;
  • 是否启用了压缩、并行查询或结果缓存;
  • RAID0阵列状态、文件系统挂载点和可用空间。

测试应使用生产数据的脱敏副本、快照副本或单独测试库。不要直接对生产库连续执行多轮全量扫描,因为它可能挤占业务缓存、增加磁盘队列,并影响其他连接的响应时间。

如果必须在业务环境中验证,应选择低峰期、限制并发、设置超时,并提前确认备份和恢复方案。只读查询虽然不直接修改业务数据,但仍可能产生临时文件、增加缓存淘汰和I/O压力。

2. 让数据规模覆盖不同缓存状态

建议至少准备三种数据状态:

  1. 数据集明显小于数据库有效缓存;
  2. 数据集接近数据库缓存容量;
  3. 数据集明显大于数据库缓存容量。

第一种状态容易得到较快结果,但它主要反映内存命中后的表现。第三种状态更接近持续从存储读取的场景。若只测热缓存,可能高估全量查询能力;若只测冷缓存,又可能低估长期运行中反复查询同一批数据的体验。

热缓存测试可以先执行数次相同查询,待读取量和耗时趋于稳定后开始计数。冷缓存测试应在隔离测试实例中通过受控重启、重新挂载测试卷或重新准备测试副本实现。不要在生产机上直接执行清空系统缓存的命令,这会影响同机所有服务,且清缓存本身可能引入额外干扰。

3. 区分扫描测试和完整返回测试

建议将查询分为两组。

第一组只返回少量聚合结果,用于观察数据库扫描和计算:

SELECT
    COUNT(*) AS row_count,
    SUM(metric_col) AS metric_sum,
    MIN(event_time) AS min_time,
    MAX(event_time) AS max_time
FROM fact_table;

第二组返回完整结果集,用于观察业务端到端体验。此时应明确记录:

  • 返回行数;
  • 返回列数;
  • 结果集字节数;
  • 客户端是否将结果写入文件;
  • 客户端是否实时消费结果;
  • 数据库服务器与客户端之间的连接位置;
  • 传输开始、首行返回和最后一行返回时间。

如果查询结果很大,客户端处理速度可能成为瓶颈。比如客户端程序在收到数据后进行格式转换或写入机械磁盘,那么最终时间不能归因于数据库或RAID0本身。

4. 验证执行计划,而不是只看SQL文本

对于MySQL类数据库,可以在测试副本上使用支持该版本的执行分析语法,例如:

EXPLAIN ANALYZE
SELECT
    COUNT(*) AS row_count,
    SUM(metric_col) AS metric_sum
FROM fact_table;

对于PostgreSQL类数据库,可以使用:

EXPLAIN (ANALYZE, BUFFERS, TIMING)
SELECT
    COUNT(*) AS row_count,
    SUM(metric_col) AS metric_sum
FROM fact_table;

具体语法取决于数据库版本。EXPLAIN ANALYZE会实际执行查询,因此应仅对只读SQL和测试副本使用。重点查看以下内容:

  • 是否发生全表扫描或大范围扫描;
  • 实际扫描行数与估算行数是否接近;
  • 是否使用了索引、索引回表或索引覆盖;
  • 是否出现临时排序、哈希溢出或磁盘临时文件;
  • 数据库报告的读取块数量;
  • 是否存在锁等待或并发等待;
  • 执行计划是否在每次测试中保持一致。

如果估算行数与实际行数差异很大,先不要把性能归因于NVMe或RAID0。统计信息过期、数据分布变化和参数估计错误,都可能让数据库选择不合适的计划。

四、推荐的采样方法

一个可复现的基础测试可以按以下流程进行。

第一步:建立测试记录

为每个测试点建立一条记录,至少包含:

  • 测试时间;
  • 数据库版本;
  • 数据集大小和行数;
  • 缓存状态;
  • 查询文本或查询指纹;
  • 并发数;
  • 样本数;
  • 单次耗时和分位数;
  • 扫描字节数;
  • CPU、内存、iowait;
  • 设备读取带宽、I/O等待和队列;
  • 返回结果集大小;
  • 错误和超时数量。

不要只保存最终平均值。保留每次查询的原始耗时,才能识别第一次加载、后台任务或偶发I/O抖动。

第二步:先做单并发基线

每个查询先执行1次预热,再执行多次正式采样。全量查询成本较高时,可以先使用5次预热加10次正式采样进行粗测;如果需要稳定比较P95或P99,正式样本应增加到30次以上。

单并发基线应分别进行:

  • 冷缓存扫描;
  • 热缓存扫描;
  • 聚合返回;
  • 完整结果返回。

每次测试前确认没有残留的上一次查询、锁等待或异常临时文件。不同测试之间不要随意修改索引、缓存大小或查询参数,否则前后结果失去可比性。

第三步:逐步增加并发

在单并发结果稳定后,再执行并发2、4、8等测试。每一级并发都应使用相同数据、相同查询和相同缓存状态。

建议观察两组变化:

  • 查询数量增加后,总吞吐量是否继续提高;
  • 单个查询的P95、P99和I/O等待是否快速恶化。

如果并发4已经让设备利用率接近饱和,就没有必要为了得到更高的数字直接把并发提升到几十。压测产生的结果可能只说明系统被强行压满,而不能代表实际业务容量。

第四步:使用独立存储测试解释数据库结果

数据库测试应是主结果,存储基准只能用于辅助定位。若测试环境有独立的测试挂载点,可以用只读顺序读取测试观察底层卷的大致上限:

四、推荐的采样方法配图

fio --name=seqread \
  --filename=/srv/test-volume/read-benchmark.bin \
  --rw=read \
  --bs=1M \
  --iodepth=32 \
  --numjobs=1 \
  --direct=1 \
  --runtime=60 \
  --time_based \
  --group_reporting

该命令只能在已准备好的隔离测试目录和测试文件上运行,不能把 --filename 指向数据库文件、生产数据目录或裸块设备。执行前应确认测试文件不会覆盖业务数据,并确保测试卷有足够空间;测试结束后只清理测试文件即可回滚影响。这个测试不应与数据库查询同时运行,否则两者会争抢同一组I/O资源。

如果独立顺序读取速度很高,但数据库全量查询速度较低,说明数据库处理链路中还存在CPU、缓存、执行计划、临时文件或并发等待等因素。反过来,如果数据库扫描速度接近存储测试结果,并且iowait和设备延迟同时升高,才更像是存储路径成为主要限制。

五、如何解释测试结果

下面的示例数据只用于说明分析方法,不代表某台双960G NVMe RAID0香港服务器的实测结果。

五、如何解释测试结果配图

场景示例现象更可能的解释
冷缓存、单并发扫描240GB耗时96秒,读取约2.5GB/s,iowait明显升高查询受到持续存储读取影响
热缓存、单并发查询耗时降至28秒,磁盘读取很低,CPU占用较高数据主要来自缓存,CPU或聚合计算成为主要环节
冷缓存、并发4总读取量增加,但每条查询P95明显上升,设备等待时间变长多个扫描共享I/O队列,阵列接近饱和
完整结果返回数据库执行时间较短,但客户端最后一行返回很慢网络、客户端解析或目标文件写入限制了端到端速度

情况一:RAID0读取速度增加,但查询时间没有同比缩短

这并不矛盾。数据库可能存在以下情况:

  • 查询只读取了缓存,没有充分访问两个SSD;
  • 单条扫描线程没有形成足够的并行I/O;
  • CPU已经处理不过来;
  • GROUP BY或ORDER BY产生了大量临时计算;
  • 扫描后还需要解压、转换或执行表达式;
  • 查询被锁、连接池或其他任务排队;
  • 执行计划没有真正扫描目标数据。

因此,不能用“两块盘的理论带宽”直接除以表大小来预测查询耗时。

情况二:磁盘利用率不高,但查询依然很慢

磁盘利用率低不代表服务器没有性能问题。重点要结合CPU、执行计划和数据库等待事件判断。

如果CPU用户态接近饱和,说明查询可能受聚合、排序、表达式或数据解码限制。若CPU不高、磁盘也不忙,但查询时间很长,应检查锁等待、临时文件、连接排队和执行计划估算误差。

如果数据库实际读取块数量很少,却耗时很长,则更应优先检查锁、事务状态和客户端行为,而不是继续更换存储测试参数。

情况三:热缓存比冷缓存快很多

这说明结果高度依赖缓存。此时应同时报告两种结果:

  • 冷缓存耗时:代表首次访问或工作集超出缓存后的表现;
  • 热缓存耗时:代表重复访问稳定数据时的表现。

生产业务若经常重复查询相同数据,热缓存结果有参考价值;如果每天都扫描新增的大量数据,冷缓存或混合缓存结果更接近实际。表大小、索引大小和数据库缓存容量发生明显变化后,需要重新测试。

情况四:并发增加后总吞吐量提高,但P99急剧上升

这是典型的容量边界信号。比如并发从1增加到4时,总扫描吞吐量仍在增长,但P95从40秒升到90秒,P99超过两分钟,说明系统可能已经接近I/O、CPU、内存或临时空间的某个上限。

对于离线批处理,可以根据总完成量选择合适的并发;对于在线查询,则应以业务规定的P95或P99为边界,而不是继续追求更高的总吞吐量。

六、双盘RAID0在测试中要特别注意什么

双960G NVMe RAID0的优势通常体现在多个I/O请求能够分布到两个设备,持续读取或并发访问可能获得更高的总带宽。但实际收益受以下因素影响:

六、双盘RAID0在测试中要特别注意什么配图

  • RAID0条带大小是否适合当前访问模式;
  • 数据库是顺序扫描还是随机访问;
  • 查询是否能产生足够的并发I/O;
  • 文件系统和数据库缓存是否已经命中;
  • 数据库是否把临时文件、数据文件和日志文件放在同一阵列;
  • 并发查询是否共享同一I/O队列;
  • 阵列、文件系统和数据库的状态是否正常。

全表扫描往往更容易体现持续读取能力,但排序、哈希、索引回表和多表关联可能包含大量随机访问或临时文件操作。一次顺序读取测试不能覆盖这些场景。

还要注意,RAID0没有冗余能力。任一成员盘发生故障,都可能导致整个阵列上的数据库文件不可用。因此,性能测试合格不等于部署风险合格。测试环境和正式环境都应有独立备份,并通过恢复演练确认备份可用。不要把RAID0本身当作备份,也不要在没有恢复方案的情况下为了追求全量查询速度而直接承载唯一数据副本。

七、用测试结果判断是否够用

可以用“业务目标+资源余量”而不是单一读写速度做判断。

如果业务是夜间报表或离线统计,重点关注:

  • 单次全量查询能否在任务窗口内完成;
  • 多个报表同时运行时是否互相拖慢;
  • 临时空间是否足够;
  • 并发提高后总吞吐量是否仍然增长;
  • 数据增长后完成时间是否可预测。

如果业务是在线查询,重点关注:

  • 目标并发下的P95和P99;
  • 查询超时和错误率;
  • 热缓存与冷缓存差异;
  • 全量查询是否影响其他在线请求;
  • 查询期间CPU、内存和I/O是否仍有余量。

可以用扫描吞吐量做一个初步时间估算。例如,测试得到稳定冷缓存扫描速度约2.5 GB/s,待处理数据量为1 TB:

  • 1 TB按十进制计算为1000 GB;
  • 1000 GB ÷ 2.5 GB/s = 400秒;
  • 400秒约为6分40秒。

这只是理想的顺序扫描估算。实际数据库耗时还要加上执行计划、聚合、临时文件、并发排队和结果输出成本。多查询并发时,也不能简单把单查询速度乘以并发数,因为共享设备会在达到饱和后出现等待。

当出现以下任一情况时,应重新做一轮完整测试:

  • 表数据或索引大小增长到原来的明显比例;
  • 工作集已经接近或超过数据库有效缓存;
  • 查询计划发生变化;
  • 数据库、内核、文件系统或RAID配置变更;
  • 并发目标提高;
  • P95或P99超过业务阈值;
  • I/O等待、临时文件或Swap开始持续增长;
  • 生产查询从聚合结果变成完整结果集返回。

最终应保存一组可复现的基线:同一数据集、同一查询、同一缓存状态、同一并发数,以及对应的P50/P95、扫描GB/s、CPU、内存、iowait、I/O队列和结果集大小。这样才能判断双960G NVMe RAID0香港服务器的数据库全量查询能力是来自真实的存储收益,还是只来自热缓存、低并发或客户端测量口径的变化。

目录结构
全文