索引——查询加速的基石
一、为什么需要索引想象一下你有一本 1000 页的书没有目录也没有页码。你想找到“索引优化”这一节唯一的办法就是从第 1 页开始一页一页翻下去——直到翻到第 800 页才找到目标。这就是全表扫描。SQL Server 中的索引本质上就是书的目录。它是一种B-Tree平衡树结构能够以对数级别的时间复杂度定位到数据行而不是线性扫描整个表。索引的核心价值大幅减少数据读取量从百万行缩小到几行避免排序和临时表帮助查找唯一值加速JOIN、GROUP BY、ORDER BY二、索引的两大核心类型2.1 聚集索引Clustered Index数据行的物理排序依据聚集索引的叶子节点就是完整的数据行。每张表只能有一个因为数据行只能按一种物理顺序存储。推荐每张表都有聚集索引没有聚集索引的表称为堆表Heap。-- 创建聚集索引通常在主键上自动创建 CREATE CLUSTERED INDEX IX_Orders_OrderDate ON Orders(OrderDate); 常见问题主键默认就是聚集索引但这不是绝对的。你可以将主键设为非聚集索引也可以在不做主键的列上创建聚集索引。2.2 非聚集索引Non-Clustered Index叶子节点存储的是指向数据行的指针如果表有聚集索引指针就是聚集索引键如果是堆表指针就是 RID每张表可以有多个最多 999 个常用于频繁作为查询条件的列WHERE、JOIN、ORDER BY-- 创建非聚集索引 CREATE NONCLUSTERED INDEX IX_Orders_CustomerID ON Orders(CustomerID);2.3 核心区别对比对比项聚集索引非聚集索引每表数量1最多 999叶子节点内容完整数据行指针RID 或聚集键查找方式直接定位先找指针再回表查数据物理顺序决定表存储顺序不影响表存储顺序空间占用较大包含所有列较小仅索引列指针三、索引是如何工作的Seek vs Scan3.1 Seek查找利用 B-Tree 结构直接定位到符合条件的行复杂度O(log N)对于 100 万行数据Seek 大约只需要 20 次逻辑读取3.2 Scan扫描遍历整个索引或整个表的所有行复杂度O(N)100 万行数据 至少 100 万次读取3.3 一个直观的演示-- 准备测试数据100万行 DROP TABLE IF EXISTS Orders; CREATE TABLE Orders ( OrderID INT IDENTITY(1,1), OrderDate DATE, CustomerID INT, Amount DECIMAL(10,2) ); -- 插入100万条随机数据 WITH Numbers AS ( SELECT TOP 1000000 ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n FROM sys.all_columns a CROSS JOIN sys.all_columns b ) INSERT INTO Orders (OrderDate, CustomerID, Amount) SELECT DATEADD(day, n % 3650, 2020-01-01), (n % 10000) 1, ROUND(RAND(CHECKSUM(NEWID())) * 10000, 2) FROM Numbers; GO -- 第一次查询无索引全表扫描 SET STATISTICS TIME ON; SET STATISTICS IO ON; SELECT * FROM Orders WHERE CustomerID 12345; -- 观察输出逻辑读取次数很大约 3000-4000 次 -- 执行计划Table Scan-- 添加索引 CREATE NONCLUSTERED INDEX IX_Orders_CustomerID ON Orders(CustomerID); GO -- 再次查询 SELECT * FROM Orders WHERE CustomerID 12345; -- 观察输出逻辑读取次数大幅降低约 10-20 次 -- 执行计划Index Seek Key Lookup四、常见索引误区以及正确做法❌ 误区 1索引越多越好事实每增加一个非聚集索引INSERT、UPDATE、DELETE操作都要同时维护该索引。索引不是免费的。建议定期使用 DMV 检查未使用的索引及时删除。❌ 误区 2所有表都应该有聚集索引事实90% 的表都应该有聚集索引但存在少数例外——比如极端插入性能要求的日志表堆表可能更快没有聚集索引的插入开销。建议除非有明确的理由否则为每张表创建聚集索引。❌ 误区 3WHERE 列建了索引就能加速事实以下情况索引可能被忽略对索引列使用函数WHERE YEAR(OrderDate) 2024数据类型隐式转换WHERE OrderID 123OrderID 是 INT前导通配符WHERE Name LIKE %Smith低选择性列如性别男/女优化器可能认为扫描更便宜建议定期查看执行计划确认索引是否被实际使用。五、快速诊断你的索引健康吗5.1 找出从未使用过的索引SELECT OBJECT_NAME(i.object_id) AS TableName, i.name AS IndexName, i.type_desc, s.user_seeks, s.user_scans, s.user_lookups, s.user_updates FROM sys.indexes i LEFT JOIN sys.dm_db_index_usage_stats s ON i.object_id s.object_id AND i.index_id s.index_id WHERE OBJECTPROPERTY(i.object_id, IsUserTable) 1 AND (s.user_seeks s.user_scans s.user_lookups 0 OR s.user_seeks IS NULL) AND i.name IS NOT NULL ORDER BY ISNULL(s.user_updates, 0) DESC;对于user_seeks/scans/lookups全为 0 的索引说明自上次服务重启以来从未被查询使用过建议评估后删除。5.2 找出缺失的索引SQL Server 自动推荐SELECT migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks migs.user_scans) AS Score, mid.statement AS TableName, mid.equality_columns, mid.inequality_columns, mid.included_columns, migs.user_seeks, migs.avg_total_user_cost FROM sys.dm_db_missing_index_groups mig INNER JOIN sys.dm_db_missing_index_group_stats migs ON migs.group_handle mig.index_group_handle INNER JOIN sys.dm_db_missing_index_details mid ON mig.index_handle mid.index_handle WHERE mid.database_id DB_ID() ORDER BY Score DESC;按 Score 降序排列Score 越高表示创建该索引的潜在收益越大。5.3 检查索引碎片SELECT OBJECT_NAME(ips.object_id) AS TableName, i.name AS IndexName, ips.avg_fragmentation_in_percent, ips.page_count, ips.avg_page_space_used_in_percent FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, LIMITED) ips JOIN sys.indexes i ON ips.object_id i.object_id AND ips.index_id i.index_id WHERE ips.avg_fragmentation_in_percent 30 ORDER BY ips.avg_fragmentation_in_percent DESC;碎片率 30% 时建议重新组织或重建索引。六、核心总结要点说明索引的本质B-Tree 结构相当于书的目录聚集索引每表一个叶子节点存完整数据行非聚集索引每表最多 999 个叶子节点存指针Seek vs ScanSeek 是 O(log N)Scan 是 O(N)索引不是万能的维护有成本查询写法会影响使用定期检查清理无用索引补充缺失索引处理碎片一句话记住本期内容索引是查询加速的基石但缺少索引一定慢索引过多也一定慢——关键在于平衡。下一期预告复合索引与列顺序的奥秘为什么(A, B)和(B, A)完全不同如何选择索引列的先后顺序什么是覆盖索引如何避免 Key Lookup实战一个复合索引如何同时加速 5 种查询

相关新闻

AI 音乐生成版权水印:可听不等于可商用

AI 音乐生成版权水印:可听不等于可商用

AI 音乐生成版权水印:可听不等于可商用 一、AI 音乐生成不能只看好不好听 AI 音乐生成工具越来越顺手,输入风格、情绪、节奏,就能得到一段听起来完整的音频。但工程化落地不能只看可听性。真正上线到商业内容、短视频、游戏或广告里&#xff…

2026/7/7 4:38:04阅读更多 →
CLAW世界模型:用连续隐动作重构具身智能的几何基础

CLAW世界模型:用连续隐动作重构具身智能的几何基础

1. 项目概述:CLAW不是新玩具,而是世界模型演进的关键拐点“CLAW:端到端学习连续隐动作世界模型”——这个标题里没有一个词是凑数的。CLAW不是某个公司随手起的营销代号,它代表一种明确的技术范式转向;“端到端”不是修…

2026/7/7 4:38:04阅读更多 →
Gitleaks与Trivy集成:构建容器镜像密钥泄露的CI/CD全链路防护

Gitleaks与Trivy集成:构建容器镜像密钥泄露的CI/CD全链路防护

1. 项目概述:为什么镜像里的密钥是“定时炸弹”?在容器化部署成为主流的今天,我们习惯于将应用及其依赖打包成一个Docker镜像,然后像分发标准件一样部署到任何环境。这个过程看似优雅,却隐藏着一个巨大的安全盲区&…

2026/7/7 4:38:04阅读更多 →
OpenCV cv2.cvtColor 与 NumPy 切片转换:3 种方法性能与内存实测对比

OpenCV cv2.cvtColor 与 NumPy 切片转换:3 种方法性能与内存实测对比

OpenCV BGR/RGB转换性能对决:3种方法实测与工程选型指南当你第一次用OpenCV读取图像后直接调用matplotlib显示时,那种诡异的蓝色调画面至今让我记忆犹新——这大概是每个计算机视觉开发者都会经历的"成人礼"。BGR与RGB的通道顺序差异&#xff…

2026/7/7 5:48:12阅读更多 →
PyTorch 1.13 CIFAR-10 图像分类实战:5层CNN网络实现85%+准确率

PyTorch 1.13 CIFAR-10 图像分类实战:5层CNN网络实现85%+准确率

PyTorch 1.13 CIFAR-10 图像分类实战:5层CNN网络实现85%准确率 1. 项目概述与数据准备 CIFAR-10数据集作为计算机视觉领域的经典基准,包含60,000张32x32像素的彩色图像,涵盖10个常见物体类别。每类包含6,000张图像,其中50,000张用…

2026/7/7 5:48:12阅读更多 →
Redis集群创建时出现“Node xxx.xxx is not empty”问题处理

Redis集群创建时出现“Node xxx.xxx is not empty”问题处理

事件回顾 今日重启服务器的Redis集群,登录Redis节点,通过cluster info发现Docker重启后,集群的Redis服务器IP地址发生变化, 导致Redis集群节点未连接,因此需要重新创建Redis集群,但在重新创建Redis集群时出…

2026/7/7 5:48:12阅读更多 →
AI数据中心液冷焊接设备怎么选?5家品牌横评

AI数据中心液冷焊接设备怎么选?5家品牌横评

NVIDIA Vera Rubin平台官宣100%全液冷——单GPU 2300W、单机柜200kW,风冷极限被彻底击穿。根据NVIDIA路线图,Rubin将于2026年Q3启动批量出货,全球AI数据中心散热方案将不可逆地从"风冷为主"切换至"液冷为王"。而对液冷系…

2026/7/7 5:48:12阅读更多 →
Agent 的经验飞轮:当 AI Agent 学会从执行中沉淀可复用知识

Agent 的经验飞轮:当 AI Agent 学会从执行中沉淀可复用知识

每次打开一个新的 Agent 会话,都是一次从零开始的冒险。你知道目标是什么,Agent 也知道目标是什么。但接下来发生的事情就像一场没有地图的探索:它会尝试几种工具调用,碰壁几次,调整参数,重新尝试&#xff…

2026/7/7 5:48:12阅读更多 →
人工智能训练师-理论知识考点速记(下):模型训练+测试+运维

人工智能训练师-理论知识考点速记(下):模型训练+测试+运维

一、模型训练核心考点速记 1.1 训练全流程结构图 ┌──────────────────────────────────────────────────────────────┐ │ 模型训练全流程 │ │ …

2026/7/7 5:43:12阅读更多 →
从GitHub安全案例解析常见漏洞与防护实践

从GitHub安全案例解析常见漏洞与防护实践

1. 项目概述:从GitHub Trending看安全实战 最近在GitHub Trending上看到一个项目,叫 skills4/skills ,它因为一些安全漏洞案例被大家讨论。这其实是一个挺典型的场景:一个旨在展示或教授某种技能的仓库,本身却成了安…

2026/7/7 4:43:43阅读更多 →
MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

# MLT 2026启示:因果推理与概率建模驱动下一代LLM应用## 一、背景与挑战:从“黑箱预测”到“可信推理”2026年6月,第7届机器学习与趋势国际会议(MLT 2026)将在悉尼召开。会议议程中,“因果与可解释机器学习…

2026/7/7 2:56:31阅读更多 →
通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

1. 项目概述与漏洞背景最近在梳理一些历史OA系统的安全风险时,通达OA v11.6版本中的一个老漏洞又进入了我的视线。这个漏洞位于/general/bi_design/appcenter/report_bi.func.php文件中,是一个典型的SQL注入点。虽然这个漏洞的利用方式看起来并不复杂&am…

2026/7/7 1:03:28阅读更多 →
Acunetix v24.8 深度解析:DAST漏洞扫描器核心原理与DevSecOps实践

Acunetix v24.8 深度解析:DAST漏洞扫描器核心原理与DevSecOps实践

1. 项目概述:Acunetix v24.8 高级版漏洞扫描器深度解析作为一名在网络安全领域摸爬滚打多年的老兵,我深知一款趁手的“兵器”对于安全测试工作意味着什么。今天要聊的,就是Web应用安全测试领域里一个响当当的名字——Acunetix。特别是其v24.8…

2026/7/7 0:02:41阅读更多 →
国产化信创改造:达梦/人大金仓适配与多数据库兼容方案实战(SpringBoot)

国产化信创改造:达梦/人大金仓适配与多数据库兼容方案实战(SpringBoot)

国产化信创改造:达梦/人大金仓适配与多数据库兼容方案实战(SpringBoot) 🌐 演示地址:http://ruoyioffice.com | 📦 源码1GitHub:ruoyi-office | 📦 源码2GitCode:ruoyi-o…

2026/7/7 0:02:41阅读更多 →
CentOS 7/8 SSH 连接失败:5步系统性排错流程与决策树

CentOS 7/8 SSH 连接失败:5步系统性排错流程与决策树

CentOS SSH连接故障排查:从基础检查到深度修复的完整指南引言当你尝试通过Xshell或其他SSH客户端连接CentOS服务器时,突然遭遇"Connection refused"或"Connection timed out"的错误提示,这种经历对任何运维人员或开发者来…

2026/7/7 0:02:41阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/7 5:11:21阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/7 5:11:21阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/7 5:11:21阅读更多 →