全部博文(471)
分类: Mysql/postgreSQL
2012-06-28 11:28:25
表中一共只有2000多条数据,我的删除语句是delete from jx1114 where xnxqh='2011-2012-2'
这个删除只要删除80多条数据,但是却执行了将近3分钟的时间,这张表引用了其他一个表的主键作为外键。
删除表记录非常慢有好几个原因:
1.机器性能问题,cpu被其他进程占用。这种方式最好解决,在进程管理器中关掉几个进程,释放出cpu用于处理删除记录操作;
2.sql语句本身优化,使用exists或者not exists比用“=”来的快;
3.表的关联关系影响了删除的速度。如果目标表和其它表建立了关联关系过多也会造成处理效率下降问题。如A表的和B表建立外关联的话,而B表又是一张很大的表,删除A表的记录时oracle执行过程是先在A表中选中一条记录进入待删除区,然后进行关联关系分析的,就是对B表进行全表查询一遍。同理如果A表和其它表 也有关联的话相同的查询也会在其它表中执行查询,等所有关联表查询完成确定没有引用关系的话,A表中选中记录会被打一个可以删除的标记,然后执行A表下一条的查询工作。值得注意的是被标记为可删除标记的记录不是立刻被删除的,删除操作一直要等到A表符合删除记录全部被打成可删除标记,删除操作才会被执行。如果有一条没有被标记成可删除标识的话,oracle 数据库会根据你设置给出相应的处理。
4.表与表引用关系存储在系统表dba_constraints 中,要有dba权限才能够执行的。查询语句如下:注意要更换'TableName':
select owner,constraint_name,CONSTRAINT_TYPE,TABLE_NAME
from dba_constraints
where r_constraint_name in (select CONSTRAINT_NAME from dba_constraints where table_name='TableName');
如果这个还不能解决问题的话。还有更复杂的办法。
5.使用oralce自带10046 的trace。该方法使用方法需要谨慎的,随用随关的。启用当前session的跟踪:
SQL> alter session set sql_trace=true; -- 开启trace
Session altered.
此时的SQL操作将被跟踪:
SQL> select count(*) from dba_users;
COUNT(*)
----------
34
结束跟踪:
SQL> alter session set sql_trace=false; --关闭trace
Session altered.