Repository navigation
Benchmarking
简体中文 | English
本页说明基准测试的方法、已有结果和后续计划。每项结果都会标明测试环境;尚未测量的项目会注明仍在计划中。
服务端每次更新称为一个 tick;通常每秒更新 20 次,每次的目标耗时不超过 50 毫秒。
当前服务端基准通过 skript-reflect 调用 System.nanoTime():操作返回后立即记录总耗时(wallNs),校验查询和结果计数不计入其中。每 tick 运行的观察器另行记录相邻两次执行的最大间隔(gapNs)。观察窗口从操作开始持续到返回后再等待一个 tick,因此与总耗时的结束时刻不同;这个间隔也不是直接从服务端内部测得的单个 tick 耗时。
本页和自动生成的报告以六位小数显示毫秒,完整保留纳秒计时值;JSON 报告和 CI 历史保存原始的整数纳秒值。纳秒只是计时单位,不代表单次结果具有纳秒级准确度;调度、JVM 垃圾回收(GC)、其他插件、数据库执行和脚本恢复运行的时机都会影响读数。
超过 5000 行的读取会失败,不会保存部分结果。写入时,一条语句绑定的值超过 30000 个,插件会将其拆成多条语句。这些限制可以避免请求无限增大,但允许执行的大批量写入仍可能拉长 tick。
从列表变量执行 insert many 时,插件跨 tick 分段读取源变量。每段最多处理 4096 个步骤,每 64 步检查一次时间,运行约 2 毫秒后暂停。单个值的转换仍可能超过 2 毫秒,因此这只是控制主线程耗时的目标,并非硬上限。整次写入可能需要更多 tick 才完成;写入语句返回前,脚本应保持源变量不变。
测试分别观察了三个方面:
-
JVM 基准中的插入耗时。 一次 5000 行的
insert many,在 Intel Xeon Platinum 8573C 上用时 8.022 毫秒,在 AMD EPYC 7763 上用时 8.241 毫秒。对应的 CI 记录分别位于dev/bench/intel-xeon-platinum-8573c/data.js和dev/bench/amd-epyc-7763-64-core-processor/data.js。 -
当前服务端读写。 使用
System.nanoTime()分别记录五种数据库的操作总耗时,以及 tick 观察器的最大执行间隔。当前实测结果见下表。 - 旧版数据库驱动的行为。 另一项测试连续写入二十批、每批 5000 行,MySQL 用时 17.04 秒,PostgreSQL 和 MariaDB 各用时 1.99 秒。对其中一批,MySQL 服务端统计到 5038 条语句,其中 5000 条是插入;MariaDB 统计到 2 条,其中 1 条是多行插入。这些数据来自旧版 MySQL 插入路径,只对应当时的驱动设置。
当前服务端基准在 SQLite、MySQL、MariaDB 和 PostgreSQL 上对比 5000 行的 insert many 与手写 SQL。MySQL 默认使用参数化多行 INSERT,每条语句最多绑定 30000 个值;其他 JDBC 路径使用预处理批次。手写 SQL 则是一条直接写入值的多行 INSERT,其字符串构造不计入耗时。两者的耗时差异还包含插件读取源变量、参数绑定和写入形式的成本,不能全部归因于 ORM 映射。MongoDB 只执行插件读写用例,并明确跳过 SQL 对照。
手写 Skript 循环如果只写入普通变量,测到的是内存操作,不能用来比较数据库写入性能。
tick 超出量是观察到的最大 tick 间隔减去 50 毫秒,负数按零计算。这个指标能显示 tick 延迟,却不能直接给出写入在主线程上用了多久;在一个正常 tick 内完成的工作也不会显示为超出。表中的“热读”和“热写”只是指在其他用例之后再执行一次 5000 行读取或写入,不表示缓存一定已预热。
tick 作业分别对下表的五种数据库实现(后端)运行 100、500、1000、2500、5000 和 10000 行的插件写入与读取,并在最后再次执行 5000 行写入和读取。支持 SQL 的数据库另有 5000 行的插件与原始 SQL 对照。输入行只填充 id 列,这样比较集中在行的传输和存储,而不是某种六列数据组合。
先确认每种数据库跑了哪些用例,以及结果来自什么环境。这张表用于检查测试覆盖范围,不比较耗时。
-
后端:被测数据库;SQLite 使用插件的
"JDBC"连接类型。 - 插件多行数与重复测试:是否运行前述六种行数,以及最后重复执行的 5000 行读写。
-
原始 SQL 对照:是否用
execute query和execute update执行手写 SQL,与插件语句对照。MongoDB 不支持 SQL,因此跳过这组对照;它的插件读写仍会测试。 - 新版 CI 结果:本次工作流链接、运行主机的 CPU 型号,以及数据库容器镜像或数据库名称。
| 后端 | 插件多行数与重复测试 | 原始 SQL 对照 | 新版 CI 结果 |
|---|---|---|---|
| SQLite | 已完成 | 已完成 | Run #4,AMD EPYC 7763,SQLite |
| MySQL | 已完成 | 已完成 |
Run #4,Intel Xeon 6973P-C,mysql:8.4
|
| MariaDB | 已完成 | 已完成 |
Run #4,AMD EPYC 7763,mariadb:11.4
|
| PostgreSQL | 已完成 | 已完成 |
Run #4,AMD EPYC 7763,postgres:17
|
| MongoDB | 已完成 | 跳过:不支持 SQL |
Run #4,Intel Xeon 6973P-C,mongo:8
|
SQL 对照分别记录 pluginwrite、pluginread、rawwrite 和 rawread 日志;MongoDB 则在插件读写后明确记录 SKRIPTORM_BENCH=SKIP。
Run #4 于 2026-10-03 在提交 6476c9b 上完整通过,环境为 Paper 26.2 build 124、Skript 2.16.2、
Java 25.0.4.1、Linux 6.17.0-1022-azure 和 4 个可见 CPU。下表是该次运行的 5000 行结果。
以下实测表以毫秒显示,保留六位小数:78.302884 ms 对应 78302884 ns,没有取整到毫秒。
正常情况下,tick 观察器每隔约 50 ms 执行一次,因此采用纳秒计时后,测得的间隔仍可能是几十毫秒;
计时精度与操作本身花了多久是两回事。每个数只代表共享 GitHub runner 上的一次运行,
不能据此给数据库做普遍排名。
各数据库都处理 5000 行,将任务规模固定下来,便于观察本次运行中读写等待时间和 tick 延迟的差异。总耗时与 tick 间隔放在一起,可以区分“整次操作等待较久”和“期间某次服务端更新迟到”;数据库操作即使跨多个 tick 完成,也不意味着这些 tick 全都被阻塞。
- 后端:执行这一行测试的数据库,环境见上一表。
- 写入总耗时、读取总耗时:从开始执行插件语句到返回的时间,包含源变量读取或结果存储、数据库执行,以及等待脚本恢复运行的时间;后续校验不计入。
- 写入最大 tick 间隔、读取最大 tick 间隔:在对应操作的观察窗口内,tick 观察器相邻两次执行之间的最大间隔。窗口持续到操作返回后一个 tick;正常间隔约为 50 毫秒,超过它表示观察到更新延迟,这不是插件独占主线程的时间。
| 后端 | 写入总耗时 | 写入最大 tick 间隔 | 读取总耗时 | 读取最大 tick 间隔 |
|---|---|---|---|---|
| SQLite | 735.828866 ms | 65.767643 ms | 103.186998 ms | 103.066121 ms |
| MySQL | 462.517747 ms | 50.395059 ms | 78.302884 ms | 78.218777 ms |
| MariaDB | 685.122311 ms | 66.066614 ms | 95.789059 ms | 95.813175 ms |
| PostgreSQL | 585.103286 ms | 66.926809 ms | 94.172914 ms | 94.082624 ms |
| MongoDB | 717.433104 ms | 50.968606 ms | 78.761947 ms | 78.579400 ms |
这张表把同一数据库的 10000 行写入与后续重复的 5000 行写入放在一起,检查更大的任务是否伴随更长的 tick 间隔。重复的 5000 行应与上一表中首次执行的 5000 行对照,才能观察重复运行时的变化;不能将不同规模的两列直接相减,作为缓存预热的收益。
- 后端:执行写入的数据库,与上一表使用同一次运行。
- 10000 行写入耗时:首次执行 10000 行写入的总耗时,计时范围与上一表相同。
- 最大 tick 间隔:10000 行写入开始到返回后一个 tick 的观察窗口中,tick 观察器相邻两次执行之间的最大间隔。
- 5000 行热写入耗时、热写入最大 tick 间隔:六种行数用例结束后,再执行一次 5000 行写入时的总耗时和最大观察器执行间隔;两者的统计窗口与上一表相同。“热写入”只是重复运行的标签,不保证某个缓存已经预热。
| 后端 | 10000 行写入耗时 | 最大 tick 间隔 | 5000 行热写入耗时 | 热写入最大 tick 间隔 |
|---|---|---|---|---|
| SQLite | 1501.908676 ms | 94.670715 ms | 779.342861 ms | 50.628368 ms |
| MySQL | 1398.534310 ms | 51.944607 ms | 684.881529 ms | 50.515912 ms |
| MariaDB | 1149.905662 ms | 101.135769 ms | 675.078706 ms | 50.746686 ms |
| PostgreSQL | 1255.801227 ms | 95.786030 ms | 623.383051 ms | 50.885682 ms |
| MongoDB | 1196.824500 ms | 53.798503 ms | 683.646486 ms | 50.583169 ms |
以下对照与上面的曲线分开运行,四列都是处理 5000 行的总耗时。插件写入包含跨 tick 读取输入变量的时间,原始 SQL 的字符串则在计时前就已构造完成。两者走的是不同的 写入路径,因此耗时比值不能直接当成 ORM 自身的开销。
每行固定数据库和行数,横向比较插件与手写 SQL 的完整调用时间,能看出这两条读写路径在本次环境中的耗时差异。写入与读取分列,是因为输入变量处理、数据库执行和结果存储的成本不同,不能合成一个“ORM 性能”数字。
- 后端:两条读写路径使用的数据库。
-
插件写入、插件读取:分别执行
insert many与select many的总耗时,包含插件在主线程上的变量处理与等待数据库返回的时间。 -
原始 SQL 写入、原始 SQL 读取:分别执行
execute update和execute query的总耗时。写入 SQL 在计时前构造完毕;读取仍包含结果存储。 - 不适用(不支持 SQL):MongoDB 不接受 SQL,不能运行这组原始 SQL 用例。这不表示它没有读写能力,也不表示耗时为零;其插件读写照常列出。
| 后端 | 插件写入 | 原始 SQL 写入 | 插件读取 | 原始 SQL 读取 |
|---|---|---|---|---|
| SQLite | 727.519482 ms | 17.148948 ms | 112.968835 ms | 104.414372 ms |
| MySQL | 586.972838 ms | 46.793973 ms | 76.245264 ms | 91.635107 ms |
| MariaDB | 628.867037 ms | 74.916475 ms | 91.608649 ms | 89.937610 ms |
| PostgreSQL | 778.881589 ms | 61.349564 ms | 99.224999 ms | 102.880893 ms |
| MongoDB | 685.494020 ms | 不适用(不支持 SQL) | 78.850687 ms | 不适用(不支持 SQL) |
下面展开同一次 Run #4 的 MariaDB 结果,环境为 AMD EPYC 7763、mariadb:11.4,其余服务端版本与前文一致。数据取自原始纳秒记录,没有另外启动一轮测试。
固定数据库和运行环境,再改变行数,可以观察任务变大时总耗时和 tick 延迟如何变化。将首次与重复的 5000 行放在一起,也能观察相同任务在不同运行顺序下的表现;每项只有一次采样,不能据此判断耗时必然随行数线性增长。
- 操作:插件写入或读取;“重复”指其他行数用例结束后再次执行。
- 请求行数:脚本要求处理的行数,不一定是实际返回的行数。
- 总耗时:从开始执行语句到返回的时间,包含变量处理、数据库执行和等待恢复运行,后续校验不计入。
- 最大 tick 间隔:操作开始到返回后一个 tick 的观察窗口中,tick 观察器相邻两次执行之间的最大间隔,正常约为 50 毫秒。
- tick 超出量:最大 tick 间隔减去 50 毫秒,负数按零计算,便于直接观察相对正常更新周期的延迟。
- 结果:操作是否成功。10000 行读取超过 5000 行上限,记录的是查询被拒绝时的耗时,不是成功读取 10000 行的耗时。
| 操作 | 请求行数 | 总耗时 | 最大 tick 间隔 | tick 超出量 | 结果 |
|---|---|---|---|---|---|
| 写入 | 100 | 183.019540 ms | 77.813136 ms | 27.813136 ms | 成功 |
| 读取 | 100 | 58.978086 ms | 54.904413 ms | 4.904413 ms | 成功 |
| 写入 | 500 | 125.585622 ms | 50.931863 ms | 0.931863 ms | 成功 |
| 读取 | 500 | 59.719091 ms | 59.571377 ms | 9.571377 ms | 成功 |
| 写入 | 1000 | 122.445042 ms | 50.273827 ms | 0.273827 ms | 成功 |
| 读取 | 1000 | 59.743000 ms | 59.761403 ms | 9.761403 ms | 成功 |
| 写入 | 2500 | 139.899172 ms | 64.122445 ms | 14.122445 ms | 成功 |
| 读取 | 2500 | 79.123322 ms | 79.081254 ms | 29.081254 ms | 成功 |
| 写入 | 5000 | 685.122311 ms | 66.066614 ms | 16.066614 ms | 成功 |
| 读取 | 5000 | 95.789059 ms | 95.813175 ms | 45.813175 ms | 成功 |
| 写入 | 10000 | 1149.905662 ms | 101.135769 ms | 51.135769 ms | 成功 |
| 读取 | 10000 | 59.551810 ms | 59.517446 ms | 9.517446 ms | 被拒绝:超过 5000 行读取上限 |
| 写入(重复) | 5000 | 675.078706 ms | 50.746686 ms | 0.746686 ms | 成功 |
| 读取(重复) | 5000 | 82.868479 ms | 82.686620 ms | 32.686620 ms | 成功 |
本次 10000 行写入的总耗时和最大 tick 间隔都高于 5000 行写入;重复的 5000 行写入总耗时相近,但最大 tick 间隔更短。100 行写入却比 500 行慢,可见这次结果并未随行数单调增加。运行顺序、启动阶段和共享主机活动都可能影响单次读数,但仅凭这张表无法确认原因,也不能只按行数推算耗时。
各用例的影响行数或保存行数已校验,10000 行读取也按预期被拒绝。gap 不是插件 CPU 耗时,而是 tick
观察器的最大执行间隔,其中包含调度和共享主机活动。本次运行早于提交 21898af 的 MySQL
max_allowed_packet 修复;要测量当前 MySQL 路径,需要在该修复推送后重新运行。
下文区分现有测量结果与后续计划,并说明各项指标适合在哪一层采集。
为了分析耗时来源,基准测试分为三个层次:
- A:不启动 Paper 的 JVM 基准。 JMH 是用于反复运行并测量 Java 代码的基准测试工具,用例放在独立模块中。纯逻辑可以不连接数据库单独测量;现有插入用例使用内存 H2,因此结果同时包含数据库执行和插件代码的成本。
- B:真实数据库。 测量数据库往返、语句解析与执行、连接池及事务提交等成本。通过 Testcontainers 启动各后端实例,沿用集成测试的配置。
- C:Paper 服务端。 观察脚本执行期间的耗时和 tick 间隔,包括主线程读取源变量、保存查询结果等工作。基准脚本运行在一次性服务端上;内存占用与 MSPT(每个 tick 的耗时,单位毫秒)的分布仍需另外测量。
分层测量有助于定位问题:值转换属于 A,驱动批处理属于 B,主线程上的 Skript 变量读写属于 C。
触发器的总耗时包含数据库操作、主线程上的变量处理,以及等待脚本恢复运行的时间,不能单独用于判断服务端是否卡顿。最长 tick 间隔可以显示延迟,但不能准确拆分这些成本。
Paper 基准脚本目前记录 wallNs、gapNs、tick 数,以及影响行数或已保存行数。报告从 gapNs 推算 tick 超出量,并校验行数。这套测量尚不能单独得出主线程 CPU 耗时、数据库耗时、内存分配量或 MSPT 百分位。
下表列的是后续测量计划,不是实测成绩。把指标与适合采集它的层次放在一起,是为了决定应在插件代码、真实数据库还是完整服务端中补充测量,从而定位耗时或内存占用来自哪里。
指标是要观察的量;拟记录内容说明具体测什么;测量层引用前文的 A(不启动 Paper 的 JVM 基准)、B(真实数据库)和 C(Paper 服务端)。列在表中不代表当前用例已经输出该指标。
| 指标 | 拟记录内容 | 测量层 |
|---|---|---|
| 主线程耗时 | 操作在服务端主线程上占用的时间 | C |
| 后台耗时 | 数据库工作在后台线程执行的时间 | B、C |
| 触发器延迟 | 从语句开始到脚本恢复运行的总耗时 | B、C |
| 吞吐量 | 每秒处理的行数和值数 | A、B、C |
| 提交给驱动的语句数与行数 | 在 JDBC 边界统计调用与行数 | B |
| 数据库收到的语句数与写入行数 | 通过数据库计数器统计 | B |
| 每次操作的内存分配量 | 每次操作分配的字节数 | A、B |
| 峰值堆占用 | 操作期间持续采样得到的最大堆占用 | B、C |
| 回收后堆占用 | 用例结束并执行垃圾回收后的堆占用 | B、C |
| MSPT 分布(p50、p99、最大值) | 每个 tick 的耗时:中位数(p50)、99% 的 tick 不超过的耗时(p99)和最大值 | C |
要把触发器总耗时拆成数据库耗时与主线程耗时,还需要额外的测量手段;目前的 wallNs 包含这两部分,以及脚本等待恢复运行的时间。
在共享 CI 主机上,相同测试的耗时曾相差 10% 至 20%;语句数则比较稳定。因此,CI 可以直接检查计数,耗时只作报告,不据此判定构建失败。
前述旧版二十批写入测试对每个数据库使用相同脚本和表定义。MySQL 与 MariaDB 共用 SQL 方言,但驱动发送批次的方式不同:当时在 JDBC 层,插件只提交一个批次;服务端计数却显示,Connector/J 将其中 5000 行逐行发送。单看耗时无法找到这个原因。当前 MySQL 路径改为参数化多行插入,下述旧计数不能作为新版的预期值。
基准模块还会统计 JDBC 层的调用。使用内存 H2 和通用 JDBC 路径时,一次 5000 行、六列的插入提交了一个批次。插件准确报告了 5000 个影响行,调用结束后表中也有 5000 行。
ServerSideCountIntegrationTest 测量真实数据库收到的语句。对 MySQL 系数据库,它在插件调用前后读取 Questions,扣除探针自身的开销,同时读取 Innodb_rows_inserted、Com_insert 和 Com_stmt_execute。这些计数覆盖整个服务器,因此测试会先检查是否有其他连接;如有,就只报告数字,不据此断言结果。驱动版本和设置会改变计数,所以结果会连同环境信息一起记录,不作为 CI 通过条件。
在一次 5000 行测试中,MySQL 8.0.46 和 8.4.11 各记录到 5038 条语句,其中 5000 条是插入语句(comInsert=5000、comStmtExecute=0)。MariaDB 11.4.13 记录到 2 条语句,其中一条是多行插入(comInsert=1、comStmtExecute=1)。测试账号无法从 MariaDB 取得插入行数。PostgreSQL 16.15 为目标表统计到 5000 行、为整个数据库统计到 5057 行,但现有计数器无法提供语句数;等待异步统计视图更新用了 814 毫秒。各后端都由插件报告了准确的 5000 个影响行,表中也确实增加了 5000 行。
这些都是每个后端在一台主机上的单次结果,不代表区间。日志记录了环境信息:os=Linux 6.17.0-1022-azure arch=amd64 cores=4 java=25.0.4.1 commit=81526798498f5ad30068fcb3299f2085062f868d。即使在同一次工作流中,MySQL 和 MariaDB 的作业运行于 Intel Xeon Platinum 8370C,PostgreSQL 的作业则运行于 AMD EPYC 7763。比较耗时时应看各作业实际使用的主机。
测试读取 PostgreSQL 的 pg_stat_user_tables.n_tup_ins 和 pg_stat_database.tup_inserted,并等待这些异步统计数据更新。它们统计行数,无法推算发送了多少条语句。要获得语句数,需要配置 pg_stat_statements 并重启服务器,或在协议层另行计数。
JMH、Testcontainers 和基准历史记录已用于现有测试。其余工具列为补充指标的可选方案。
这张表说明前述测量计划可以用什么工具实现,供选择测量方法时参考,不比较工具本身的速度。用途说明要收集哪类数据,括号中的 A、B、C 对应测量层;工具列出可使用的库或诊断工具;作用解释它能提供什么证据,以及仍需另外记录什么。
| 用途 | 工具 | 作用 |
|---|---|---|
| 微基准(A) | JMH | 正式计时前先运行代码,让 JVM 完成常见优化;用独立进程测量,并避免 JVM 把结果未被使用的被测代码删掉 |
| 提交给驱动的语句数与行数(B) |
datasource-proxy 或计数驱动 |
统计 JDBC 调用;单次批量调用实际包含多少行,还需另行记录 |
| 数据库收到的语句数与往返数(B) | 数据库会话计数器或网络抓包 | 观察驱动批处理后的实际行为;结果受驱动版本和连接参数影响 |
| tick 采样的百分位(C) | HdrHistogram | 对多次 tick 采样计算分位数 |
| 真实数据库(B) | Testcontainers | 启动测试数据库;复用实例可减少重复启动时间 |
| 历史与对比 | benchmark-action/github-action-benchmark |
按 CPU 和后端保存结果;耗时变化不作为构建失败条件 |
| 内存分配与停顿 | JMH -prof gc、JFR、async-profiler |
分析内存分配,以及 JVM 为垃圾回收等操作暂停线程的时间 |
| MSPT(C) | Paper 的 tick 采样 | 获取服务端自身记录的 tick 耗时 |
基准模块直接声明 JMH 及其注解处理器,因为现成的 Gradle 插件不支持本项目使用的 Gradle 版本。运行 ./gradlew :benchmarks:jmh,结果会写入 build/benchmarks/results.json。可用 -Pbenchmarks.filter=<正则> 选择用例,或用 -Pbenchmarks.forks=1 缩短本地测试时间。JMH 的注解处理器生成 Java 代码,因此基准类使用 Java。
编译、单元测试、ktlint 和集成测试编译已纳入 CI。
tick 基准作业会因结果行数不符或脚本报告错误而失败,不会因耗时变化而失败。后续如增加其他稳定且可复现的检查指标,可以与受共享 CI 主机影响较大的耗时数据分开处理。
基准结果只与硬件环境相近的运行比较。
-
CI 历史由基准测试 action 保存在
gh-pages分支的dev/bench/<slug>/下,按 CPU 型号分组。ubuntu-latest可能分配不同处理器:同一提交的两次运行分别落在 AMD EPYC 9V74 和 Intel Xeon Platinum 8573C 上,插入用例耗时相差 1.32 倍。每个作业都会单独记录 CPU 型号;新版 tick 结果还按后端分开,存于dev/bench/<slug>/tick-ns/<backend>/。 -
gh-pages分支用于存储基准数据,本项目没有从中发布图表站点。JMH 原始结果位于dev/bench/<slug>/data.js;tick 结果位于dev/bench/<slug>/tick-ns/<backend>/。 - **
benchmarks/baseline.json**仅供本地参考,不作为 CI 阈值。benchmarks/baseline.environment.txt记录生成基线时使用的机器。
结果还会记录 JDK、操作系统、CPU、容器镜像、数据库驱动、Paper 和 Skript 的版本,以及提交和工作区状态,以便区分代码变动与环境变动。
-
阶段 0:微基准。 为值转换、结果存储、批次输入及
insert many发送的语句数建立 JMH 用例,保存 JSON 结果和参考基线。 - 阶段 1:数据库矩阵。 为各后端、各类语句和不同表结构加入语句计数。
-
阶段 2:服务端 tick(已配置五种后端)。
./gradlew serverBenchmark启动装有 Skript、skript-reflect 和本插件的 Paper 服务端,运行server-benchmark/skript中的脚本。脚本通过SKRIPTORM_BENCH输出以纳秒为单位的耗时及最长 tick 间隔;如果写入行数不符或脚本输出FAIL,任务就会失败。CI 另行检查一次读取最多 5000 行、每条写入语句最多绑定 30000 个值的限制。夜间和按需运行的tick矩阵将结果存入dev/bench/<slug>/tick-ns/<backend>/。详见读取行和写入行。脚本计时器无法提供 MSPT 百分位。 - 阶段 3:压力与故障测试(计划中)。 覆盖并发、取消、执行途中断开数据库、查询期间重载插件、超限结果与批次,以及连接池耗尽。
- 阶段 4:完善 CI 报告(计划中)。 增加上述尚缺的指标,将稳定的正确性检查与耗时趋势分开处理。
- 在线玩家。 空闲服务端上的结果无法预测大量玩家和实体活动时的表现。
- 长时间运行。 现有用例仅持续数秒,无法发现几天后才出现的泄漏。
- 未纳入测试的驱动。 通用 JDBC 连接可使用本仓库未测试的驱动;MySQL 的结果不能代表这些驱动。
- PostgreSQL 语句数。 当前统计信息能提供行数和事务数,不能统计单条操作发送的语句数。
- 跨机器的绝对耗时。 耗时必须结合测试环境解读。
skript-orm
参考
实用指南
skript-orm (English)
Reference
- Connections
- Tables
- Raw statements
- Writing rows
- Reading rows
- Updating and deleting
- Affected rows
- Errors and waiting
- Transactions
- Types
Practical guides
Wiki 由仓库中的 README 和 docs/ 自动生成。修改文档请到仓库提交,直接编辑 Wiki 的内容会在下次同步时被覆盖。
This wiki is generated from the README files and docs/ in the repository. Please submit changes there; direct wiki edits are overwritten on the next sync.