有一个项目,大概跑了两年数据量比较大,偶尔会出现系统效率响应变慢的情况。 由于现场不能停工,第一反应是不是历史数据太大了,使用存储过程,分批把历史数据删除剩下几百万。 发现两个模块都慢,最终分析代码发现两个模块都调用了一个方法。方法执行的 sql 如下:
怀疑可能是 UNION 走了全表导致的,然后加了如下索引
CREATE INDEX IX_STATUS_WCSSOURCE ON TTT(STATUS, WCSSOURCE);
系统就正常了。
但是没搞懂的是,为什么清除历史数据了还是慢,而且期间运行了几年也没有卡顿。 备注:使用的是删除,主键此时还是比较大的数值
1
bg7lgb 12 天前
最简单的处理方法 ,explain plan ,看下 SQL 的执行计划。
这个组合索引并不优,不如分开建索引。 |
2
spiffing 12 天前
换成临时表都比 union 快
|
3
fffq 12 天前
表要做碎片整理吧
|
4
irisdev 12 天前
这个表名起的
|
5
deng884720982 OP @bg7lgb 感谢,主要不能理解的是为什么数据量不大,查询也会有影响
|
6
deng884720982 OP @fffq 能详细说一下吗?
|
7
deng884720982 OP @irisdev 表名是我替换了的,防止被同事看到
|
8
deng884720982 OP @spiffing 主要不能理解的是为什么数据量不大,查询也会有影响
|
9
deng884720982 OP sql 查询已经进行优化了,但是没理解的是为什么数据量不大也会受影响,之前都是正常运行的
|
10
shangfabao 12 天前
你这个也不放个 explain plan ,我们表结构索引都不知道,怎么给你看么
|
11
spiffing 12 天前
@deng884720982 union 一般来说包含两个操作 select 和 distinct 。 你可以试试 union all 。
|
12
shangfabao 12 天前
并且你要是执行的是 del,表空间没有释放,你尝试新建个表,把数据倒进去,再执行这个 sql 试试
|
13
sujin190 12 天前
@deng884720982 #6 他的意思可能是,数据虽然删除了,但是磁盘文件的对应空间并没有回收然后重写让剩下的数据在一起,那么此时查询数据库从磁盘读取数据时,每次读取依然只能读取的非常少的条数,读取磁盘的次数和数据量并没有显著降低,那么查询性能自然也不会有很大提升,不过如果你是时间有序数据,只是删除更早以前的数据,那这个问题影响应该不会很大吧
|
14
deng884720982 OP @sujin190 这个我当时也考虑了的,把相关数据删除之后,使用数据库文件收缩把,空间回收了的
|
15
deng884720982 OP @shangfabao 好的,感谢由于事态比较紧急,处于夜间突发,所以当时没有考虑太多,只是尝试性加了一下索引,下次尝试这个思路试一下
|
16
bg7lgb 12 天前
@deng884720982 数据删除后,存储空间会碎片化,可以 coalesce 合并一下;同理 index 的节点也有类似的问题,可以 rebuid 一下,你会发现空间释放出来很多。
|
17
zlowly 12 天前
真没必要太多猜测和尝试,正如一楼所说的,数据库性能
|
18
zlowly 12 天前
真没必要太多猜测和尝试,正如一楼所说的,explain plan ,看下 SQL 的执行计划,基本就能定位数据库性能问题。
|
19
ala2008 12 天前
对的同意楼上,不要猜测,看下执行计划。数据库做的这方面还是很好的
|
20
dog82 12 天前
t.*,x.*这种写法要改正
sql 优化的问题,一定要贴执行计划 优化的两个重要原则 1 建立高效索引 2 避免回表 |
21
fengpan567 12 天前
因为 MIN(WCSSOURCE)子查询,可不得全表扫描吗
|
22
ilucio 12 天前
应该是 MIN(WCSSOURCE)导致的,只对 WCSSOURCE 字段加索引效果应该是一样的
|
23
Plutooo 12 天前
在新建索引之前有没有存在其他索引 比如索引 a ,之前正常运行有可能是能命中索引 a 所以没问题,数据多以后优化器选错索引或者未命中索引,具体还是要通过执行计划分析
|
24
deng884720982 OP 感谢大家的回复,从事相关行业并不是很久。学习到了,sql 问题先使用 explain 去分析,看是否走的全表扫描。以及楼上老哥说的,存储空间碎片化的问题。十分感谢
|