加入收藏 | 设为首页 | 会员中心 | 我要投稿 站长网 (https://www.027zz.com/)- 区块链、应用程序、大数据、CDN、数据湖!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

SQL Server查询卡顿?5个索引优化技巧提速3倍

发布时间:2026-11-06 11:26:58 所属栏目:MsSql教程 来源:DaWei
导读:  去年过年时,老张在机房啃着凉透的酱牛肉饼,监控屏右下角时间跳到凌晨一点零七分,SQL Server那台DELL R740的风扇声突然从“嗡”变成“嘶——”,像有人用指甲刮黑板。我盯着那个跑不动的查询计划,执行时间从十八秒蹦到

  去年过年时,老张在机房啃着凉透的酱牛肉饼,监控屏右下角时间跳到凌晨一点零七分,SQL Server那台DELL R740的风扇声突然从“嗡”变成“嘶——”,像有人用指甲刮黑板。我盯着那个跑不动的查询计划,执行时间从十八秒蹦到两百一十三秒,再蹦到“已取消”。


  不是参数嗅探问题。我原以为是统计信息陈旧,手动UPDATE STATISTICS全库跑完,它照旧卡在Nested Loops那一层——左表扫了三十七万行,右表每行触发一次Key Lookup,查完索引还得回表翻六次页。我当场把笔记本合上,听见老张手机响了,他接起来说“妈,饺子煮破了您别捞渣……”然后挂掉,顺手把饼渣抖进机柜缝隙里。


  第一个技巧:删掉那个叫IX_OrderHeader_CustId_Status的非聚集索引。它建在CustomerId和OrderStatus上,但98%的查询只查Status,且Status只有三个值(‘P’/‘S’/‘C’),等于给全表加了个装饰性滤网。我删之前截图存证,王工在隔壁喊“你敢动生产索引?”,我没理,删完重跑——没提速。但锁等待降了七成。这事儿我敢打包票,他不信可以看sys.dm_tran_locks里的resource_description字段,里面全是KEY: 5:72057594038321152 (819444328a9e),密密麻麻堆着。


文章配图,仅供参考

  第二个技巧:在OrderDetail表上补一个覆盖索引,字段顺序是[OrderId] INCLUDE ([ProductId], [Quantity], [UnitPrice])。不是[OrderId, ProductId],更不是[ProductId, OrderId]——后者连WHERE条件都对不上。上线前我让实习生小李跑了个测试脚本,结果他误把ORDER BY写成GROUP BY,脚本卡死三分钟,最后是老张过去拔了他网线。这事我说不准,但他拔网线时窗外雨停了,屋顶漏水顺着空调管道滴到UPS电源指示灯上,“嘀”一声灭了绿灯。


  第三个技巧:把Customer表上那个唯一约束UK_Customer_Email删了,换成交叉索引IX_Customer_Email_IsDeleted(Email, IsDeleted)。不是因为邮箱重复——它根本没重复。是因为每次更新IsDeleted字段时,UK_Customer_Email触发全表扫描校验唯一性,而Email列有三百七十二万行,中间还有八千多个NULL。这玩意儿我三年前就该动,拖到去年腊月廿三才下刀。动手前我灌了半杯速溶咖啡,粉结块沉在杯底,喝到最后是苦渣子味。


  第四个技巧:干掉所有SELECT ,尤其别在视图里嵌套视图还带COUNT() OVER()。我们那个销售日报视图,里面套着采购分析视图,采购分析视图里又调了一个UDF函数,函数里有一句“SELECT @val = COUNT(1) FROM dbo.BigTable WITH (NOLOCK)”——这个WITH (NOLOCK)根本没用,因为它在子查询里,外面套着TOP 1000,SQL Server照样会走序列扫描。我把它砍掉那天,运维刘姐正抱着一摞A4纸进来贴封条,说财务系统要“年度结账”,纸角翘起来刮着我的手背,有点疼。


  第五个技巧:把主键改成聚集索引?别扯了。我们订单表的主键是GUID,早年说是“防爬虫”,后来发现爬虫根本不在意UUID。现在聚簇索引建在OrderDate上,但OrderDate字段经常被update,导致页分裂率常年23%。上周我试着改回IDENTITY(1,1),还没提交就被DBA总监拦住了,他端着保温杯站在门口,杯盖拧开一半,水汽往上冒,说“这得走变更流程”。我说流程走完明年春节可能还在等审批。他点头,把杯盖拧紧了,转身时后颈有道浅浅的晒痕——去年海南团建晒的,没消干净。


  优胜劣汰。不是说好的索引活下来,差的被淘汰;是跑得慢的SQL先被业务侧毙掉,毙掉之前没人看你有没有索引,只看它返回不返回。去年除夕前十分钟,运营催报表,开发甩锅到数据库,DBA组三个人挤在我工位旁盯屏幕,小李把键盘敲得噼啪响,老张叼着根没点的烟,烟丝簌簌往下掉。我点了F5,这次十秒出结果。没人鼓掌,老张把烟收回去,说“我那饼盒还剩俩”。王工蹲下去捡掉在地板上的U盘,U盘背面贴着张便利贴,字迹潦草:“查完帮我看看SSIS包为啥总失败”。我瞥了一眼没接话。


  机房空调今天又坏了。冷凝水沿着桥架滴到光纤盒上,发出“嗒、嗒、嗒”的声音。我懒得报修——这声儿比报警阈值低,监控系统根本抓不到。刚才试运行新索引时,SQL Server Agent作业里一个Step状态卡在“正在运行”,但日志里最后一行是“Executed as user: NT SERVICE\\SQLSERVERAGENT. The step succeeded.”。我看了五分钟,关了SSMS。桌面上还摊着半张没撕完的工单打印纸,边角卷起来了。


  现在手边这台笔记本散热口烫得能煎蛋,风扇转速已经拉满。我不打算重装驱动,就让它这么烧着。明天上午九点,我得去参加那个叫“云原生数仓架构研讨会”的会,PPT第一页写着“告别SQL Server”。行吧。先让这台R740再喘三个月,够我把订单归档表分区策略改完就行。至于那个SSIS包——让王工自己看去。

(编辑:站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!