最近遇到一个怪异的现象,给大家分享一下。 有一张存储了 36w 条记录的表,存储了从 2013 年到现在的历史数据,并基于主键 retID 建了聚簇索引。
最近新增的应用访问这张表的时候,发现有些条件查不出来数据, [现象 1 ] :比如同一条记录,用 BarCode 字段能查出来,用 CKCode 就不出来。我比较两者的查询计划,发现走的索引不一样。 于是尝试重建了该表的对应字段的索引,发现没有变化。 又尝试重建了该表的聚簇索引,这下好了,建完之后,之前的 [现象 1 ] 消失了,但是整个表的记录数变成了 33w 条,有 3w 条消失了。。。
有人知道这个问题的根本原因吗?
1
tzigone 2022-03-28 11:23:10 +08:00
10 年的数据 30w ,每个月几千条,主键数据丢失涉及数据文件损坏了,找备份 roll back 吧
|
2
thinkershare 2022-03-28 11:44:40 +08:00
你最好将数据先全部先备份,数据库以页为存储, 索引和页数据都在页上, 我怀疑物理某些页在磁盘扇区上物理损坏了.
|
3
xsm1890 2022-03-28 14:03:07 +08:00
不知道这个 36w 和 33w 是不是 count()计算出来的总数;如果不是的话,那很正常,对于很多数据库及存储引擎,表总数只是维护一个大概数,并不精确。不然的话,得备份恢复下了
|
4
shyrock OP @xsm1890 #3 厉害了,我又看了一下,count ()出来的总数没变,只是数据表属性页里面的条数少了 3w 。
而且按 id 排序的话,发现中间 58000 到 90000 的 id 缺失了。 如果总数没变,不知道这些 id 跑到哪里去了。。。 |
5
shyrock OP 对这个现象我有一个 90%可能性的猜测:
这个表本来有 36w 行数据,但是因为某些物理损坏,在聚集索引中丢失了中间 3w 行记录的引用。这时候从表的属性看,数据仍然有 36w 行,而且其他非聚集索引仍然完整指向了这 36w 行记录。 当使用聚集索引时,中间的 3w 行数据查不到,但是用非聚集索引查找时能查到所有 36w 行记录。 我尝试重建聚集索引,数据库引擎为了保持数据完整性,把 3w 行记录删除掉,并且通知其他非聚集索引重建。 之后所有方式的查询结果一致,但是 3w 行记录就消失了。 |
6
xsm1890 2022-03-28 18:33:58 +08:00
@shyrock 关于 id 不见了,从你的表述来看,可能没你想的那么复杂;如果是自增 id ,可能只是单纯的 id 跳过,有很多种情况都会发生,这对业务,对数据都没有任何的影响。
|