一,优化需求分析

      通常情况下,用户会在代码评测系统中进行多次提交,DS分析返回的结果也会有很多次访问数据库存储,这时候用户接受到的评测结果就需要在数据库中搜索并返回给客户端,大批量搜索工作产生了搜索性能优化的需求。

 二,选择索引结构

SQLlite支持多种索引数据结构

B+树(平衡多路搜索树,叶子节点形成链表)

作为一种比较常见的索引数据结果,B+树支持高效范围查询和排序。它能够实现等值查询,
范围查询,排序,覆盖索引等
分析:适用于大多数常规字段(数值、时间戳、短文本),但对全文搜索或高维空间数据效率低。
索引大小可能较大(需要存储存储所有键值和行指针)。这是一套通用的索引数据结构,适用于本系统基于提交更新的时间戳搜索。

R*Tree(基于 R-Tree 的变种的多维平衡树)

这类型数据结构支持空间数据范围查询(如地理坐标、几何图形),能够快速查找与指定区域重叠的条目。

分析:高效处理多维空间查询,支持快速插入和删除操作。但仅适用于空间数据,需要显式创建虚拟表,无法直接为现有表添加 R*Tree 索引。这套OJ系统并不需要处理高维空间数据

FTS(倒排索引,记录词项到文档的映射)

能够将文本内容分词并建立词到文档的映射,支持模糊查询和关键词搜索。

分析:适用于长文本字段,支持自然语言查询(如短语匹配、布尔逻辑),可配置分词规则(如忽略大小写、停用词)缺点在于仅适用于文本数据,索引体积较大(存储所有词项的位置信息)。
需要创建虚拟表,无法直接为普通表添加 FTS 索引。虽然OJ系统提交的评测结果会存在长文本,但实际上表内查询按照提交时间批次输出,并不是利用文本内关键词检索(除了题目块内容可能有重复,其余的部分DS是根据用户提交的代码来输出评测结果,存在不确定性)。

表达式索引(生成列索引)(B+树,但键值为表达式计算结果)

能够加速基于表达式或函数的查询(如 WHERE a + b > 100),避免重复计算复杂逻辑。

分析:这类型的索引虽然能简化查询逻辑,提升复杂条件的性能,支持动态计算字段的索引,但是索引更新可能较慢,并且需要提前定义生成列,增加维护成本,并不适用与OJ系统大批量的文字输出。

总体来说,B+树虽然不适用于全文查询,但能够以完整的字段作为键,在设计上只要把时间作为索引值,B+树就能快速实现等值查询和范围搜索,且较其他数据结构有更好的搜索性能。

三,实现

CREATE INDEX `idx_analysis_results_deleted_at` ON `analysis_results`(`deleted_at`) USING BTREE;
CREATE INDEX `idx_problems_deleted_at` ON `problems`(`deleted_at`) USING BTREE;
CREATE INDEX `idx_submissions_deleted_at` ON `submissions`(`deleted_at`) USING BTREE;
CREATE INDEX `idx_testcase_results_deleted_at` ON `testcase_results`(`deleted_at`) USING BTREE;
CREATE INDEX `idx_users_deleted_at` ON `users`(`deleted_at`) USING BTREE;

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐