加入收藏 | 设为首页 | 会员中心 | 我要投稿 站长网 (https://www.51zhanzhang.com/)- 应用程序、AI行业应用、CDN、低代码、区块链!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

SQL Server数据库设计避坑12实战要点

发布时间:2026-10-17 14:10:07 所属栏目:MsSql教程 来源:DaWei
导读:  去年劳动节,我蹲在IDC机房配完最后一套SQL Server集群的AlwaysOn监听器,手还没离开键盘,运维老张端着个印着“微软Tech Summit 2019”字样的纸杯进来,里头咖啡凉得发白,他搁我显示器边沿时撞了下鼠标——屏幕正好弹出S

  去年劳动节,我蹲在IDC机房配完最后一套SQL Server集群的AlwaysOn监听器,手还没离开键盘,运维老张端着个印着“微软Tech Summit 2019”字样的纸杯进来,里头咖啡凉得发白,他搁我显示器边沿时撞了下鼠标——屏幕正好弹出SSMS里一个没关的执行计划,索引扫描那行红色箭头,歪着脖子指向一张没主键的临时表。我伸手想关,他先开口:“老板刚在群里问,咱们这库到底支不支持列存储压缩。”我说:“你让他翻sys.dm_db_column_store_row_group_physical_stats试试。”他点头走了,三秒后又探头:“哦对,销售王磊刚才打电话来问备份粒度能不能按filegroup切……”


  我就烦这种问题——不是烦王磊,是烦他电话里夹着奶茶吸管声,含糊着说“客户法务那边盯着审计日志留存期”,结果一查发现他们自己建的Audit Trail表上,audit_id居然是varchar(36)带GUID,还搞了非聚集索引+INCLUDE全字段。这个我敢打包票:三年前我们线上就爆过一次——某个凌晨三点触发了tempdb里两百多个并行线程死锁,根源就是那个GUID作为JOIN条件,在百万级AuditTrail和UserSession表之间来回转换、隐式CAST、哈希重分区,最后撑爆了workfile。可你说改?业务方甩一句“下游BI工具强依赖该字段类型”,我就只能眼睁睁看着监控大屏右下角那个“TempDB Log Waits/sec”指标抽风似的跳了十八毫秒——抖了一下,就一下,像心电图突然漏了一拍。


  先扔结论:SQL Server数据库设计避坑十二点,压根不是什么最佳实践合集,它是一张血洗淘汰名单。优胜劣汰,字面意思。谁没踩过“自增IDENTITY当分布式主键”这坑?去年五一,我原以为只要把IDENTITY列设成SEED=1, INCREMENT=100,五个应用各占一段就能高枕无忧;结果上线第三天,订单中心和物流服务同时插入时区偏移导致的主键冲突,回滚事务堆满锁队列,DBA老李在钉钉语音里吼:“快停写!你那个IDENTITY起始值是不是从负数开始写的?!”——我真写过-2147483648,但他说的其实是另一套环境里的脚本,混了。这事我说不准。


  再说那个“全文索引走WHERE CONTAINS而不是LIKE”的建议。听着挺美?呵。我们上月刚给内容中台加了个FTS,建好之后测试用CONTAINS查‘区块链’,响应稳定在八十九毫秒;可运营同学半夜跑批量脚本,拿LIKE ‘%区块链%’去扫同一张表,CPU瞬间冲到92%,还顺手拖垮了旁边报表查询的maxdop配置。我当场purge了三百七十二条 purge 规则——第一条删掉的是“DELETE FROM [LogArchive] WHERE [EventTime] < DATEADD(day,-90,GETDATE())”,第二条是“TRUNCATE TABLE [Staging_Feedback_Temp]”,第三条……算了,记不清了,反正purge完发现没卵用,因为根本没人动那张被锁定六小时的[Keyword_Index_Map],它上面有个没更新统计信息的非唯一非聚集索引,重建统计后,CONTAINS慢得跟便秘一样。后来才发现——是填充因子填错了,75%填成57%,SQL Server自己脑补成570%然后报错。谁干的?后端小陈说他按部署手册第十七页抄的。手册是谁写的?厂商销售王磊的PPT附件。


  说到王磊,他昨天又来了,拎着两盒月饼——现在才四月。说他们新出了智能索引推荐引擎,能自动生成缺失索引建议。我打开SSMS看他的demo,他点开执行计划,光标悬停在Table Scan上,界面上“智能建议”弹窗写着:“创建非聚集索引 IX_Users_Email_Hash,包含字段 Email, HashValue”。我问他:HashValue是计算列吗?他说是。“加了PERSISTED没?”他顿住,摸了下耳朵后面那个创可贴——上周五他骑自行车摔的,创可贴边缘卷了,露出一点血痂。我说你别动,你这建议连PERSISTED都没加,建出来就是个废索引,SQL Server根本不会在WHERE里走它。他讪笑:“呃…我们算法默认忽略PERSISTED标记。”


文章配图,仅供参考

  还有那个“视图上建索引必须是SCHEMABINDING”的铁律。我们曾在线上库的vw_UserActivity视图上硬怼了个聚簇索引,跑了半年没事,直到某次补丁升级完重启实例——所有依赖该视图的存储过程编译失败,因为有个同义词(Synonym)背后指向的源表名被悄悄重命名了,而SCHEMABINDING锁死了对象绑定路径,它宁可挂也不容许解析延迟。没人通知,没人测,只有一封来自DBA组的邮件,标题叫“请立刻验证所有Indexed View依赖链”,发件时间是凌晨两点零七分。我回了句“已加监控项:sys.dm_exec_query_stats.total_elapsed_time > 30000 AND object_name(object_id) LIKE 'vw_%'”,没提那个写在运维wiki第三级子页面里的“Indexed View重建checklist”,里面第一条就是“确认所有引用对象未被ALTER…RENAME”,但谁去看wiki?采购流程今年卡在合同法务审核环节,KPI折算规则改了三次,我们自动化测试用例覆盖率还是82.3%,比去年低0.7个百分点——这数据我记住了,别的记不住。


  最后一条?“不要在生产库的master数据库里建作业或临时表”。这条我早就不信了。去年劳动节下午五点四十分,我们被迫在master里临时存了一张#tmp_failover_log,只存四十分钟,只为让AG故障转移时能快速定位上次同步中断点。做完我删了,还exec sp_msforeachtable 'DROP TABLE IF EXISTS ?'; 挨个清。可今天早上巡检,发现master里还挂着一个叫sp_backup_history_bak的存储过程——不是我们建的,是某厂商部署工具留下的,连CREATE_DATE都显示为“2017-11-03”。我不知道它干啥,也没权限删。DBA老李说:“先留着,等下次patch window再处理。”我嗯了一声,盯着屏幕右下角,节点分布图上有一个无关的小红点,闪了两次,灭了。


  我现在要干的事?重写一份建库Checklist,把“是否检查sys.tables.is_memory_optimized=0”放在第一条。至于其他十一条?等下个月review会再拉群吵。先去找老张要杯热的——这次别印微软logo,换阿里云的也行,反正都是云。

(编辑:站长网)

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