0

0

高水位线引起的查询变慢解决方法

不言

不言

发布时间:2018-05-15 16:12:12

|

3835人浏览过

|

来源于php中文网

原创

众所周知,随着不断地进行表记录的DML操作,会不断提高表的高水位线(HWM),DELETE操作之后虽然表的数据删除了,但是并没有降低表的高水位,除非你使用TRUNCATE操作,进行表查询的时候,Oracle会扫表高水位以下的数据块,也就是说,扫描的时间并不会有所减少。所以DELETE删除数据以后并不会提高表的查询效率。

相关mysql视频教程推荐:《mysql教程

下面通过这个例子,用来解决高水位引起的查询变慢问题:

--例子中测试表占用表空间大小为:128M
SQL> SELECT a.bytes/1024/1024 || 'M' FROM user_segments a WHERE a.segment_name = 'TC_RES_PHY_EQP_PRO_MID_517';

A.BYTES/1024/1024||'M'
-----------------------------------------
128M

--查询一条记录成本为:4357,一致性读为:15730 耗时 0.53 秒
SQL> set autotrace  on
SQL> SELECT 1 FROM TC_RES_PHY_EQP_PRO_MID_517 a WHERE a.obj_id = 17202000000001;

         1
----------
         1


执行计划
----------------------------------------------------------
Plan hash value: 854298875

------------------------------------------------------------------------------------------------
| Id  | Operation         | Name                       | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |                            |   175 |  2275 |  4357   (2)| 00:00:53 |
|*  1 |  TABLE ACCESS FULL| TC_RES_PHY_EQP_PRO_MID_517 |   175 |  2275 |  4357   (2)| 00:00:53 |
------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("A"."OBJ_ID"=17202000000001)

Note
-----
   - dynamic sampling used for this statement (level=2)


统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
      15730  consistent gets
          0  physical reads
          0  redo size
        520  bytes sent via SQL*Net to client
        520  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

--现在删除大部分数据,只剩下一条测试数据:
SQL> DELETE FROM TC_RES_PHY_EQP_PRO_MID_517 a WHERE a.obj_id <> 17202000000001;

已删除1172857行。

--查询该段占用的表空间仍然为128M
SQL> set autotrace off
SQL> SELECT a.bytes/1024/1024 || 'M' FROM user_segments a WHERE a.segment_name = 'TC_RES_PHY_EQP_PRO_MID_517';

A.BYTES/1024/1024||'M'
-----------------------------------------
128M
SQL> COMMIT;

提交完成。

SQL> SELECT a.bytes/1024/1024 || 'M' FROM user_segments a WHERE a.segment_name = 'TC_RES_PHY_EQP_PRO_MID_517';

A.BYTES/1024/1024||'M'
-----------------------------------------
128M

--查询一条记录消耗的成本为:4316,一致性读为:15730 耗时 0.52 秒
SQL> set autotrace on
SQL> SELECT 1 FROM TC_RES_PHY_EQP_PRO_MID_517 a WHERE a.obj_id = 17202000000001;

         1
----------
         1


执行计划
----------------------------------------------------------
Plan hash value: 854298875

------------------------------------------------------------------------------------------------
| Id  | Operation         | Name                       | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |                            |     1 |    13 |  4316   (1)| 00:00:52 |
|*  1 |  TABLE ACCESS FULL| TC_RES_PHY_EQP_PRO_MID_517 |     1 |    13 |  4316   (1)| 00:00:52 |
------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("A"."OBJ_ID"=17202000000001)

Note
-----
   - dynamic sampling used for this statement (level=2)


统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
      15730  consistent gets
          0  physical reads
          0  redo size
        520  bytes sent via SQL*Net to client
        520  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

--一般情况下,表的rowid是不会变的,我们通过ALTER TABLE TABLE_NAME ENABLE ROW MOVEMENT;来打开行迁移
SQL> ALTER TABLE TC_RES_PHY_EQP_PRO_MID_517 ENABLE ROW MOVEMENT;

表已更改。

--整理碎片并回收空间
--此操作相比于ALTER TABLE MOVE:
--1.不会消耗更多的表空间
--2.可以在线执行,不会使索引失效
--3.可以使用参数CASCADE,同时收缩表上的索引
--4.ALTER TABLE MOVE之后表空间的位置肯定会发生变化,而SHRINK表空间的位置没有发生变化
SQL> ALTER TABLE TC_RES_PHY_EQP_PRO_MID_517 SHRINK SPACE;

表已更改。
--查询一条记录消耗的成本为:2,一致性读为:4 耗时 0.01 秒
SQL> SELECT 1 FROM TC_RES_PHY_EQP_PRO_MID_517 a WHERE a.obj_id = 17202000000001;

         1
----------
         1


执行计划
----------------------------------------------------------
Plan hash value: 854298875

------------------------------------------------------------------------------------------------
| Id  | Operation         | Name                       | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |                            |     1 |    13 |     2   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| TC_RES_PHY_EQP_PRO_MID_517 |     1 |    13 |     2   (0)| 00:00:01 |
------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("A"."OBJ_ID"=17202000000001)

Note
-----
   - dynamic sampling used for this statement (level=2)


统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          4  consistent gets
          0  physical reads
          0  redo size
        520  bytes sent via SQL*Net to client
        520  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
--此时占用表空间只有4M
SQL> SELECT a.bytes/1024/1024 || 'M' FROM user_segments a WHERE a.segment_name = 'TC_RES_PHY_EQP_PRO_MID_517';

A.BYTES/1024/1024||'M'
-----------------------------------------
4M

当然ENABLE ROW MOVEMENT对系统性能也有影响,在TOM的博客中找到这个关于ROW MOVEMENT的问答:

HyperWrite
HyperWrite

AI写作助手帮助你创作内容更自信

下载
You Asked
Hi Tom 
I have seen your posting on ENABLE ROW MOVEMENT which is available in 10g. It looks a 
very nice option since we can relocate and reorganize  the heap tables without any outage 
since it does not invalidate indexes. But is there any performance hit or any other 
disadvantages for using this. I would like to use this in our new application.
Rgds
Anil 
and we said...
Well, the tables have to be in an ASSM (Automatic Segment Space Managment) tablespace for 
this to work (so if they are not, you have to move them there first in order to do this 
over time).
It will necessarily consume processing resources on your machine while running (it will 
read the table, it will delete/insert the rows at the bottom of the table to move them 
up, it will generate redo, it will generate undo).
I would suggest benchmarking -- collect performance metrics about the table before and 
after performing the operation.  You would expect full scans to operate more efficiently 
after, you would expect index range scans to either be unchanged or "better" as you have 
more rows per block packed together (less data spread).  You would be looking for that to 
happen -- statspack or the tools available in dbconsole would be useful for measuring 
that (the amount of work performed by your queries over time)

也就是说,ENABLE ROW MOVEMENT也会有副作用,因为表打开行迁移之后,如果对数据进行UPDATE操作,那么系统会对数据进行DELETE操作

之后再进行INSERT操作,导致产生更多的redo和undo,并且rowid也会发生变化。
附行迁移和行连接的解释:

row chain:When a row is too large to fit into any block, row chaining occurs. In this case, the Oracle devide the row into smaller chunks. each chunk is stored in a block along
 with the necessary poiters to retrive and assemble the entire row.
row migration:when a row is to be updated and it cannot find the necessary free space in its block, the Oracle will move the entire row into a new block and leave a pointer from the orginal block to the new location. This process is called row migration.

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

669

2023.06.20

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

308

2023.06.21

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

282

2023.07.18

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

516

2023.07.19

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

257

2023.07.25

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

387

2023.08.08

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

535

2023.08.11

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

608

2023.08.14

抖音网页版入口与视频观看指南 抖音官网视频在线访问
抖音网页版入口与视频观看指南 抖音官网视频在线访问

本专题汇总了抖音网页版的入口链接、官方登录页面以及视频观看入口,帮助用户快速访问抖音网页版,提供免登录访问方式和直接进入视频播放页面的方法,确保顺利浏览和观看抖音视频。

19

2026.02.04

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
微信小程序开发之API篇
微信小程序开发之API篇

共15课时 | 1.3万人学习

php-src源码分析探索
php-src源码分析探索

共6课时 | 0.5万人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号