在Oracle数据库中按用户名重建索引的方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Oracle数据库中按用户名重建索引的方法相关的知识,希望对你有一定的参考价值。

参考技术A

  如果你管理的Oracle数据库下某些应用项目有大量的修改删除操作 数据索引是需要周期性的重建的

  它不仅可以提高查询性能 还能增加索引表空间空闲空间大小

  在ORACLE里大量删除记录后 表和索引里占用的数据块空间并没有释放

  重建索引可以释放已删除记录索引占用的数据块空间

  转移数据 重命名的方法可以重新组织表里的数据

  下面是可以按ORACLE用户名生成重建索引的SQL脚本

   SET ECHO OFF; SET FEEDBACK OFF; SET VERIFY OFF; SET PAGESIZE ; SET TERMOUT ON; SET HEADING OFF; ACCEPT username CHAR PROMPT Enter the index username: ; spool /oracle/rebuild_&username sql; SELECT REM + + || chr( ) || REM | INDEX NAME : || owner || || segment_name || lpad( | (length(owner) + length(segment_name)) ) || chr( ) || REM | BYTES : || bytes || lpad ( | (length(bytes)) ) || chr( ) || REM | EXTENTS : || extents || lpad ( | (length(extents)) ) || chr( ) || REM + + || chr( ) || ALTER INDEX || owner || || segment_name || chr( ) || REBUILD || chr( ) || TABLESPACE || tablespace_name || chr( ) || STORAGE ( || chr( ) || INITIAL || initial_extent || chr( ) || NEXT || next_extent || chr( ) || MINEXTENTS || min_extents || chr( ) || MAXEXTENTS || max_extents || chr( ) || PCTINCREASE || pct_increase || chr( ) || ); || chr( ) || chr( ) FROM dba_segments WHERE segment_type = INDEX AND owner= &username ORDER BY owner bytes DESC; spool off;

  如果你用的是WINDOWS系统 想改变输出文件的存放目录 修改spool后面的路径成

  spool c oraclerebuild_&username sql

  如果你只想对大于max_bytes的索引重建索引 可以修改上面的SQL语句

  在AND owner= &username 后面加个限制条件 AND bytes> &max_bytes

  如果你想修改索引的存储参数 在重建索引rebuild_&username sql里改也可以

  比如把pctincrease不等于零的值改成是零

  生成的rebuild_&username sql文件我们需要来分析一下 它们是否到了需要重建的程度

  分析索引 看是否碎片严重 SQL>ANALYZE INDEX &index_name VALIDATE STRUCTURE; col name heading Index Name format a col del_lf_rows heading Deleted|Leaf Rows format col lf_rows_used heading Used|Leaf Rows format col ratio heading % Deleted|Leaf Rows format SELECT name del_lf_rows lf_rows del_lf_rows lf_rows_used to_char(del_lf_rows / (lf_rows)* ) ratio FROM index_stats where name = upper( &index_name );

  当删除的比率大于 % 时 肯定是需要索引重建的

  经过删改后的rebuild_&username sql文件我们可以放到ORACLE的定时作业里

  比如一个月或者两个月在非繁忙时间运行

  如果遇到ORA 错误 表示索引在的表上有锁信息 不能重建索引

  那就忽略这个错误 看下次是否成功

  对那些特别忙的表要区别对待 不能用这里介绍的方法

lishixinzhi/Article/program/Oracle/201311/19038

MySQL如何进行索引重建操作?

在MySQL数据库中,没有类似于SQL Server数据库或Oracle数据库中索引重建的语法(ALTER INDEX ... REBUILD),那么在MySQL数据库中,是否有什么方式重建索引呢? 在官方文档中"2.11.10 Rebuilding or Repairing Tables or Indexes"中,提到下面三种方式可以Rebuild Index

 

·         Dump and Reload Method

 

·         ALTER TABLE Method

 

·         REPAIR TABLE Method

 

 

另外, OPTIMIZE TABLE也会对索引进行重建,下面我们来简单验证、测试一下,如有不对或不足的地方,敬请指正。

 

 

第一种方法(mysqldump导出然后重新导入),相当于重新CREATE INDEXES , 这里就不讨论了。下面我们来看看其它几种方法,那么要判断索引是否REBUILD了呢?我们来测试验证一下吧,新建测试表如下:

 

 

CREATE TABLE t1 (
    c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    c2 VARCHAR(100),
    c3 VARCHAR(100) )
ENGINE=InnoDB;
 
create index ix_t1_c2 on t1(c2);

 

 

 

DROP INDEX + CREATE INDEX方法

 

这种方法过于简单,这里不叙说了。其实也没有啥好说的。

 

 

 

ALTER TABLE方法

 

 

那么我们能否在MySQL中找到索引的创建或修改时间呢?经过查证,目前而言,MySQL中是没有相关系统表或视图会记录索引的创建时间的,我们可以用间接的方法来间接验证,有些方法不是特别可靠和准确,最准确的方法应该是阅读源码:

 

 

1:表的创建时间,可以间接推断索引的创建时间。因为索引的创建时间肯定在表的创建时间之后。

 

2:对应表的idb文件的修改或创建时间(若文件从创建后不曾修改过则可认为创建时间=修改时间,关于更多详细内容,参考Linux如何查找文件的创建时间,当然这种方法不是非常准确。我们知道,对于InnoDB存储引擎的表而言,对应的索引数据存储在ibd文件中,所以文件的创建时间或修改时间是间接判断索引创建时间。如果存储引擎为MyISAM的话,还有专门的索引文件MYI。

 

注意:show indexes from tablename不会显示索引创建时间

 

mysql> SELECT table_name,create_time FROM  information_schema.TABLES WHERE table_name=\'t1\';
+------------+---------------------+
| TABLE_NAME | CREATE_TIME         |
+------------+---------------------+
| t1         | 2019-10-20 08:18:33 |
+------------+---------------------+
1 row in set (0.01 sec)

 

 

然后我们对表进行ALTER TABLE t1 ENGINE = InnoDB;进行操作后,然后去验证表的创建时间,如下所示,其实ALTER TABLE xxx ENGINE=InnoDB 其实等价于REBUILD表(REBUILD表就是重建表的意思),所以索引也等价于重新创建了。

 

 

clip_image001

 

 

在另外一个窗口,我们对比t1.ibd的创建时间,如下所示,也间接验证了表和索引都REBUILD了。(这里是MySQL 8.0.18 ,如果是之前的版本,还有frm之类的文件。)

 

 

 
[root@db-server MyDB]# ls -lrt t1*
-rw-r-----. 1 mysql mysql 131072 Oct 20 08:18 t1.ibd
[root@db-server MyDB]# stat t1.ibd
  File: ‘t1.ibd’
  Size: 131072          Blocks: 224        IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 106665154   Links: 1
Access: (0640/-rw-r-----)  Uid: ( 1000/   mysql)   Gid: ( 1000/   mysql)
Context: system_u:object_r:mysqld_db_t:s0
Access: 2019-10-20 08:18:25.911990445 +0800
Modify: 2019-10-20 08:18:33.626989940 +0800
Change: 2019-10-20 08:18:33.626989940 +0800
 Birth: -
[root@db-server MyDB]# stat t1.ibd
  File: ‘t1.ibd’
  Size: 131072          Blocks: 224        IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 106665156   Links: 1
Access: (0640/-rw-r-----)  Uid: ( 1000/   mysql)   Gid: ( 1000/   mysql)
Context: system_u:object_r:mysqld_db_t:s0
Access: 2019-10-20 08:20:50.866980953 +0800
Modify: 2019-10-20 08:20:51.744980896 +0800
Change: 2019-10-20 08:20:51.744980896 +0800
 Birth: -

 

clip_image002

 

 

 

 

REPAIR TABLE方法

 

REPAIR TABLE方法用于修复被破坏的表,而且它仅仅能用于MyISAM, ARCHIVE,CSV类型的表。下面的测试环境为MySQL 5.6.41,创建测试表,然后对表进行REPAIR TABLE操作

 

 

mysql> CREATE TABLE t (
    ->     c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ->     c2 VARCHAR(100),
    ->     c3 VARCHAR(100) )
    -> ENGINE=MyISAM;
Query OK, 0 rows affected (0.01 sec)
 
mysql> SELECT table_name,create_time FROM  information_schema.TABLES WHERE table_name=\'t\';
+------------+---------------------+
| table_name | create_time         |
+------------+---------------------+
| t          | 2019-10-20 08:35:43 |
+------------+---------------------+
1 row in set (0.00 sec)

 

 

然后对表t进行修复操作,发现表的create_time没有变化,如下所示:

 

 

mysql> REPAIR TABLE t;
+--------+--------+----------+----------+
| Table  | Op     | Msg_type | Msg_text |
+--------+--------+----------+----------+
| MyDB.t | repair | status   | OK       |
+--------+--------+----------+----------+
1 row in set (0.01 sec)
 
mysql> SELECT table_name,create_time FROM  information_schema.TABLES WHERE table_name=\'t\';
+------------+---------------------+
| table_name | create_time         |
+------------+---------------------+
| t          | 2019-10-20 08:35:43 |
+------------+---------------------+
1 row in set (0.00 sec)

 

 

clip_image003

 

 

在另外一个窗

以上是关于在Oracle数据库中按用户名重建索引的方法的主要内容,如果未能解决你的问题,请参考以下文章

ora-08104 该索引对象 159639 正在被联机建立或重建

Oracle 遇到的问题

执行重建索引查询时出错(ORA-29874 和 ORA-29960)

oracle数据表分区,truncate或drop后会导致索引失效,除了重建索引有没有更好的快速解决方法?

在 SELECT 语句中按错误分组,导致 Oracle 中出现 ORA-00979 错误代码

oracle索引问题,删除再重建索引与索引分析

(c)2006-2024 SYSTEM All Rights Reserved IT常识