尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

relly 查询优化初探:索引扫描 vs 顺序扫描,谁更快?

relly 查询优化初探:索引扫描 vs 顺序扫描,谁更快? relly 查询优化初探索引扫描 vs 顺序扫描谁更快【免费下载链接】rellyRDBMS のしくみを学ぶための小さな RDBMS 実装项目地址: https://gitcode.com/gh_mirrors/re/rellyrelly 是一个用 Rust 编写的迷你关系型数据库RDBMS实现专为从零理解数据库内部原理而生。今天我们就来初探数据库**查询优化Query Optimization**中最经典的一道选择题索引扫描 vs 顺序扫描在 relly 中到底谁更快两者各自有什么优缺点阅读完这篇文章你将对数据库的查询执行机制有一个直观的认识。什么是顺序扫描从第一页扫到最后一页顺序扫描Seq Scan是最朴素、也最暴力的查询方式它从表的第一条记录开始一条一条往下读直到把整张表扫完再逐条判断是否符合查询条件。在 relly 中顺序扫描由 SeqScan 计划节点 实现。它内部调用 B 树的迭代器从起始位置一路遍历并通过while_cond闭包逐个过滤记录。更完整的组合是过滤 顺序扫描可以参考 simple-table-plan.rs 示例先用SeqScan从主键w开始顺序读取再用Filter过滤出first_name Dave的记录。整个流程就像在书里一页页翻找内容数据量越大翻得越久。什么是索引扫描沿 B 树直达目标索引扫描Index Scan的思路完全不同它先借助索引B 树直接定位到目标位置再回到数据表取出完整记录跳过大量无关数据。relly 的索引基于 BTree 实现通过SearchMode::Key精确指定要查找的键B 树会沿分支节点逐层下探复杂度仅为 O(log N)。典型的用法参考 table-index.rs 示例它实现了一条SELECT * WHERE last_name Smith查询用IndexScan结合索引键Smith直接命中目标记录。值得注意的是relly 还提供了IndexOnlyScan见 src/query.rs如果查询所需的列全部包含在索引中就可以只扫索引、完全不用回表性能还能再上一个台阶。索引扫描 vs 顺序扫描一张表看懂核心差异对比维度顺序扫描Seq Scan索引扫描Index Scan查找方式逐页、逐条遍历沿 B 树二分下探时间复杂度O(N)O(log N 命中行数)回表访问不需要通常需要按主键回表适合场景全表遍历、低过滤率高过滤率、精确/小范围查询数据量敏感度极高线性增长极低对数增长一句话总结顺序扫描的时间随数据量线性增长而索引扫描几乎不受数据总量影响只跟命中多少行有关。用 relly 亲手验证数据越大差距越悬殊理论说得再多不如动手跑一遍。relly 自带了非常合适的实验素材造数据运行 table-large.rs 示例它会向表中插入1000 万行数据包含主键、MD5 和 SHA-1 哈希字段跑索引查询运行 btree-large-query.rs 示例用SearchMode::Key在千万级数据中直接定位某一行几乎瞬间返回跑范围查询再试试 btree-range.rs 示例从指定键开始顺序输出后续记录观察命中行数对耗时的影响。当数据量只有几千行时两者的差异可能微乎其微但当数据达到千万级顺序扫描需要读取的页数成倍增加而索引扫描的耗时却几乎原地不动——这就是谁更快最直观的答案。什么时候该用索引扫描一张清单帮你判断✅返回行数极少如按主键或唯一索引精确查找→ 索引扫描完胜✅小范围查询如WHERE age BETWEEN 20 AND 25→ 索引扫描更优❌需要遍历全表如统计、聚合、无过滤条件→ 顺序扫描反而更合适❌命中行数超过全表一半→ 回表成本过高顺序扫描可能更快⚠️查询列都在索引中→ 记得用 IndexOnlyScan连回表都省了。小结查询优化的第一课通过 relly 这个迷你 RDBMS我们可以清晰看到索引扫描与顺序扫描并非绝对的谁快谁慢关键在于命中率与数据量的权衡。这正是真实数据库优化器每天都在做的取舍。理解了这一课再去看 MySQL、PostgreSQL 的EXPLAIN输出你会豁然开朗。想深入源码学习relly 的查询执行器集中在 src/query.rsB 树索引实现在 src/btree.rs配合 examples/ 目录下的示例非常适合作为你学习数据库内部的第一个项目。【免费下载链接】rellyRDBMS のしくみを学ぶための小さな RDBMS 実装项目地址: https://gitcode.com/gh_mirrors/re/relly创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表