当前位置: 首页 > news >正文

111、sqlserver 表A有1亿条数据,表中每个不同值的字段B大约有100条数据,给B字段建索引和不建索引查询时性能相差多少倍?并进行分析

1、直接结论

在该场景下,建立索引后的查询性能可能会比不建索引快上 几十万甚至上百万倍。查询时间可能从小时级或分钟级,缩短到毫秒级。

2、性能差异的核心原因

同样,我们可以用电话簿的比喻来理解:

  • 不建索引(全表扫描 - Table Scan):SQL Server 需要从头到尾扫描表中的每一条记录(1 亿条),逐一比较字段B的值是否符合查询条件。这是一个 I/O 密集型操作,速度极慢。
  • 建立索引(索引查找 - Index Seek):SQL Server 会创建一个索引结构(默认是 B + 树),这个结构就像电话簿的目录。数据库可以通过这个 “目录” 直接定位到所有B字段值符合条件的数据行,然后再去数据表中读取这些行的详细信息(如果索引不是覆盖索引的话)。

3、性能差异的量化分析

我们做一个同样粗略的量化估算:
假设:

  • 表 A 有 1 亿条 记录。
  • 每条记录大小为 1KB。
  • 存储设备是 SATA III SSD,连续读取速度约为 500MB/s。
  • B + 树索引的高度通常在 3-4 层。
(1)不建索引(全表扫描)
  • 数据量:1 亿条 * 1KB / 条 = 100GB
  • 查询时间(理论最小值):100GB / 500MB/s = 200 秒 (约 3.3 分钟)
  • 注意:这是理想情况下的最快速度。实际中,数据可能不连续存储,涉及磁盘寻道、SQL Server 的各种开销等,实际时间会远大于200 秒。
(2)建立索引(非聚集索引)

当你在 B 字段上建立非聚集索引后,查询时:

  • SQL Server 在索引中快速定位到 B 值对应的位置(O(log n) 复杂度,非常快)。

  • 从索引中获取到这些记录的聚集索引键(如果表有聚集索引)或堆指针(如果是堆表)。

  • 根据这些键或指针,去聚集索引或堆中书签查找(Bookmark Lookup)对应的完整数据行。

  • 索引查找时间:微秒(μs)级别,可忽略。

  • 书签查找时间:假设找到 100 条记录,每条记录的查找是一次随机 I/O。SSD 的随机 I/O 性能远好于 HDD,但 100 次随机 I/O 仍然需要一点时间。我们保守估计为 1-10 毫秒(ms)。

  • 总查询时间:约 1-10 毫秒。

(2) 性能差异倍数
  • 差异倍数 ≈ 200 秒 / 0.001 秒 = 200,000 倍 (基于 1ms 估算)
  • 差异倍数 ≈ 200 秒 / 0.01 秒 = 20,000 倍 (基于 10ms 估算)
    即使是最保守的估计,性能差异也在数万倍以上。

4、关于该场景的特别说明

该场景中 “每个不同值的字段 B 大约有 100 条数据”,这表示字段B的选择性(Selectivity) 非常好。

  • 选择性 = 不重复的索引值数量 / 总记录数
  • 在场景里,选择性 = (1 亿 / 100) / 1 亿 = 1/100 = 1%。

选择性越高(越接近 100%),索引的效率就越高。1% 的选择性意味着通过索引筛选后,需要访问的数据量(100 条)远小于总数据量(1 亿条),因此索引能极大地减少 I/O 操作,性能提升非常显著。

5、SQL Server 的一些额外考量

(1) 聚集索引 vs. 非聚集索引:
  • 如果字段B是表的聚集索引键,那么查询性能会更好,因为数据本身就是按照B的顺序存储的,找到索引位置就找到了数据,不需要书签查找。

  • 如果B上建立的是非聚集索引,那么查询通常会经历 “索引查找 + 书签查找” 的过程。

(2) 覆盖索引(Covering Index):
  • 如果你的查询只需要返回B字段和主键字段,那么非聚集索引本身就包含了这些信息,SQL Server
    可以直接从索引中获取数据,无需访问基表,这就是索引覆盖,性能会极高。
  • 如果你还需要查询其他字段,可以考虑将这些字段加入到非聚集索引的 包含列(Included Columns) 中,以实现索引覆盖,避免书签查找的开销。
  • 示例:CREATE NONCLUSTERED INDEX IX_A_B ON A(B) INCLUDE (Column1, Column2);
(3) 索引维护:
  • 对于 1 亿条数据的大表,索引的建立过程会比较耗时,并且会产生锁和日志。建议在业务低峰期操作。
  • 大表的索引也需要定期维护(如重建或重组),以保持其性能。

总结与建议

1、巨大的性能差异

在 1 亿条数据的表上,对查询频繁、选择性良好(1%)的字段B建立索引,查询性能可能会提升几十万倍甚至更多。

2、索引是必须的

对于这种场景,建立索引是提升查询性能的关键,几乎是必须的优化手段。

3、索引的代价

索引会占用额外的存储空间,并且会轻微降低INSERT, UPDATE, DELETE的性能。但在你的查询场景下,查询性能的收益远大于这些代价。

4、选择合适的索引类型
  • 如果B字段适合作为聚集索引键(例如,经常用于范围查询、排序等),可以考虑将其设为聚集索引。
  • 否则,建立非聚集索引即可。如果查询需要其他字段,可以考虑使用包含列来创建覆盖索引,以获得最佳性能。

在这里插入图片描述

http://www.dtcms.com/a/602919.html

相关文章:

  • 官方网站建设专家磐石网络电子商务网站建设与维护课件
  • C++ 中的栈(Stack)数据结构与堆的区别与内存布局(Stack vs Heap)
  • 设计好网站苏州网站制作电话
  • 建材做网销哪个网站好怎么做企业网站
  • JAVA后端动态代理复习
  • 网站菜单怎么做品牌推广策划
  • thinkphp 网站管理科技网站哪个好
  • C语言编译软件使用教程 | 完整的C语言编译工具介绍与使用技巧
  • [AI tradingOS] AI自动交易器 | 绩效追踪与日志
  • PcVue X 工控——工厂数字化转型与落地巡回研讨会圆满举行
  • 成都哪家做网站比较好旅游网络营销的特点有
  • 青岛社保网站官网登录上海公共招聘平台
  • 计网期末复习--选择题
  • 深入理解 Linux(7) 命令与动态库:从文件操作到程序链接的实践指南
  • 做海外购网站免费的设计网站有哪些
  • 做网站内嵌地图福州建设工程协会网站查询
  • 易语言程序反编译 | 了解易语言反编译的技术与应用
  • 用网站源码怎么做网站腾讯云网站模板
  • 做芯片代理哪个网站推广产品研发
  • 在 MySQL 中使用 `REPLACE` 函数
  • 网站建设陕西wordpress is search
  • 怎么在微信做企业网站东莞建筑设计院排名
  • 仓颉三方库开发实战:技术博客_source_map_js实现详解
  • 建站设计做英文网站用目录还是子域名
  • 网站建设谈客户说什么龙岩兼职招聘最新发布
  • 上海网站建设服务多少钱广西 网站建设
  • 铜仁市城乡住房与建设局网站陕西省两学一做网站
  • 网站商城建设公司网站开发实用技术 代码
  • 外贸网站seo推广教程游戏租号网站开发
  • AI推广公司如何借助人工智能技术提升企业品牌影响力与精准流量