加入收藏 | 设为首页 | 会员中心 | 我要投稿 草根网 (https://www.0372zz.com/)- 容器安全、云日志、云数据迁移、行业智能、数据仓库!
当前位置: 首页 > 教程 > 正文

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

发布时间:2026-11-10 08:05:48 所属栏目:教程 来源:DaWei
导读:  “这版间距又动了?!”我拿数位笔戳着设计稿,笔尖刚换过,太滑,一戳就歪出个墨点——跟去年5月那个SQL Server卡顿的凌晨一样,查不出问题,但就是慢。你记得不?那会儿产品蹲在工位边啃冷包子,前端小张耳机漏音,刷短视频外放声

  “这版间距又动了?!”我拿数位笔戳着设计稿,笔尖刚换过,太滑,一戳就歪出个墨点——跟去年5月那个SQL Server卡顿的凌晨一样,查不出问题,但就是慢。你记得不?那会儿产品蹲在工位边啃冷包子,前端小张耳机漏音,刷短视频外放声里夹着一句“老铁666”,我一边听一边盯着执行计划,心里想:完蛋,这索引建得比我们切图命名还乱。


  我原以为加个非聚集索引就能好,结果查询跑了12秒,执行计划里堆着仨嵌套循环,像我们被改废的第七版首页:状态全对、空态有、首屏也加载了,可用户就是点不动按钮。后来发现,表上已经有七个索引,六个带INCLUDE列,俩重复覆盖同一组WHERE条件——优胜劣汰不是口号,是SQL Server自己删的,不是人删的。它跑着跑着,把最没用的那个索引干掉了,换成新的,就那一晚的事。我翻日志,只看到一行:“index usage dropped below threshold”。没通知,没弹窗,也没人开站会——它比我们团队还狠。


  桌上那只马克杯早干了,杯底一圈浅褐色印子,像极了我们规范文档里那个色板里说不清的灰——RGB值没标错,但实际在IE里一渲染,偏暖,在Mac上偏冷,没人测过。索引也这样。CREATE INDEX IX_Order_CustID_Status ON Orders(CustomerID, Status) WITH (SORT_IN_TEMPDB = ON)——语法漂亮吧?执行起来?慢。因为Status列只有三个值:‘P’‘S’‘C’,选择性为零,SQL Server当场放弃走这个索引,转头去扫堆。我查了半天,才发现它连优化器提示都不理,只认统计信息新鲜度。统计信息三个月没更新,就像切图文件夹里的命名:icon_home_active@2x.png、home_icon_active@2x.png、active_home_icon_2x.png——三个文件,一个图标,没人敢删,怕断链。


  窗台上的绿萝死了半盆,叶子耷拉着,茎还绿,根早烂透了。有些索引也是这样。看着还在,ALTER INDEX … REBUILD 每周都跑,日志显示“成功”,其实数据页碎片率98%,统计信息抽样率3%,它只是假装活着。我们那次复盘,就卡在要不要删掉IX_User_Email_NonClustered——产品说“这个搜邮箱要用”,技术说“从来没人搜过邮箱”,最后谁也没删。结果上线后,登录页查询从800ms飙到3.2秒。不是新功能写的烂,是旧索引吸走了所有缓存和内存页。我查缓存池,发现72%的空间在养三个十年前建的、SELECT 用的宽索引——比小李去年提离职前留下的组件库还占地方。


  你见过执行计划里那个红色虚线箭头吗?从Index Seek直接跳到Table Scan,中间没任何解释。就像那天下午,前端小张突然推门进来,甩给我一段Vue指令:v-if=“isLoading && !isError”——他指着控制台报错说“你们后端返回的loading字段有时是undefined”。我一看API文档,写的是“必填”,但数据库里那个bit字段,允许NULL。我就顺手加了个索引过滤谓词:WHERE IsLoading IS NOT NULL。两天后,这个查询快了三倍。不是玄学,是SQL Server终于肯用索引了。可你猜怎么着?产品回头说,那页要下线了,新方案用GraphQL。我对着执行计划截图愣了两分钟,鼠标悬停在那个绿色的Index Seek上,光标变成小手,但我没点。


  显示器有点色偏,左边蓝,右边黄。我们改稿改到第九版那一刻,甲方说“整体调性要更稳重”。我就把主色#4A90E2调成#3A70C2,差20个十六进制,结果前端还原度崩了——所有阴影值全不对。索引优化也这样,改一个过滤条件,影响五个查询。你信不信,我把一个ORDER BY的列加进索引KEY,本来想提速分页,结果触发了并行计划阀值,CPU打满,其他业务全堵住。那天晚上我关掉所有窗口,只留SSMS,看着那个红色警告:“Warning: Parallelism-related waits detected”。我喝了一口干马克杯里的隔夜茶,苦的。


文章配图,仅供参考

  小张后来重写了那个分页逻辑,用OFFSET FETCH,配上覆盖索引,再关掉并行。我没参与评审,只在钉钉上回了个“ok”。不是不想说,是说完他们也改不动——那个组件库里封装了七层v-loading,底层根本吐不出原始SQL。就像我们做的第一版稿子,客户说“感觉缺了点东西”,我们改了八版,第九版才被告知,他们内部早就定了用另一家供应商的模板。我打开切图文件夹看了眼,里面还有个叫“final_v9_revised_FINAL”的文件夹,点进去,psd图层全锁着,蒙版没拼合,连栅格都没对齐。


  所以我现在看索引,就跟看切图命名一样,先看是不是能立刻删。不删也行,加个注释,写上“last used: 2023-05-17”,别写“by XiaoZhang”,他早转岗做BI了。真要用,就按最糙的来:WHERE列+ORDER BY列+SELECT列,全放KEY里,宁可索引肥一点,别让优化器纠结。至于那个色板里的灰,我懒得标了,反正上线前开发会自己调。你要问我下一步干啥?我正打算导出全部sys.dm_db_index_usage_stats,筛出三个月零使用的索引——先删,删完再说。删错了?大不了明天再建。总比留着一堆半死不活的绿萝强。

(编辑:草根网)

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