Oracle rebuild index 使用 parallel 时 与 并行度 的注意事项

一.Rebuild 索引 与 并行度 说明

在之前的Blog里整理了一些列有关索引相关的Blog,如下:

 

Oracle 索引 详解

http://blog.youkuaiyun.com/tianlesoftware/article/details/5347098

 

如何加快建index 索引 的时间

http://blog.youkuaiyun.com/tianlesoftware/article/details/5664019

 

Oracle 索引扫描的五种类型

http://blog.youkuaiyun.com/tianlesoftware/article/details/5852106

 

Oracle 索引的维护

http://blog.youkuaiyun.com/tianlesoftware/article/details/5680706

 

Oracle alterindex rebuild 与ORA-08104 说明

http://blog.youkuaiyun.com/tianlesoftware/article/details/6538928

 

在索引create 和rebuild的时候,在CPU 允许的情况下,我们可以使用parallel来加快操作的速度。但是这里有一个注意的问题,有关索引的并行度,这个对表同样要注意。

 

对于OLTP类型的数据库,除非只用于做统计、报表类的表或索引,建议不对相关表或索引调置并行度。在数据库有开启并行查询的情况下,在表或索引上存在默认并行度,将导致数据库优先采用全表或全索引扫描的执行计划,另外将生成多个并行子进程,对于OLTP类应用将反而降低相关SQL的执行效率。

 

       有关parallel,官网的说明如下:

http://docs.oracle.com/cd/E11882_01/server.112/e26088/statements_7002.htm#i2159323

 

The parallel_clause letsyou parallelize creation of the table and set the default degree of parallelismfor queries and the DML INSERT, UPDATE, DELETE,andMERGE after table creation.

 

(1)    NOPARALLEL Specify NOPARALLEL forserial execution. This is the default,即并行度为1.

 

2PARALLEL  Specify PARALLEL ifyou want Oracle to select a degree of parallelism equal to the number of CPUsavailable on all participating instances times the value ofthe PARALLEL_THREADS_PER_CPU initialization parameter.

 

3PARALLEL integer Specificationof integer indicates the degree of parallelism, which is thenumber of parallel threads used in the parallel operation. Each parallel threadmay use one or two parallel execution servers. Normally Oracle calculates the optimumdegree of parallelism, so it is not necessary for you to specify integer.

 

       Oracle在并行处理时,会启动多少个并行进程来同时执行任务,并行度越高, 并行进程越多,执行速度 会越快,默认是noparallel,如果我们设置并行度为default值,那么此时的并行度是:

服务器CPU数*每个CPU启用的线程数(PARALLEL_THREADS_PER_CPU)

 

       所以一般我们建议使用Noparallel,或者将并行度设置为1,而不是default。

 

       可以通过dba_tables 和 dba_indexes 视图的degree 字段来查看相关对象的并行度。

 

       要注意的就是在我们用并行来rebuild索引的时候,rebuild结束后,我们索引的并行度也会改成我们rebuild的并行度,所以在我们rebuild 结束之后还需要对索引的并行度进行一个修改操作。

 

 

二.示例

测试环境: win7 +oracle 11.2.0.1

 

SQL> select * from v$version where rownum=1;

 

BANNER

-----------------------------------------------------------------------------

Oracle Database 11g Enterprise EditionRelease 11.2.0.1.0 - 64bit Production

 

 

--查看并行参数:

SQL> show parameter parallel_max_servers

 

NAME                                 TYPE        VALUE

----------------------------------------------- ------

parallel_max_servers                 integer     20

 

SQL> show parameter PARALLEL_THREADS_PER_CPU

 

NAME                                 TYPE        VALUE

----------------------------------------------- ------

parallel_threads_per_cpu             integer     2

 

 

--测试表Dave信息:

SQL> select count(*) from dave;

 

 COUNT(*)

----------

333798

 

SQL> col segment_name for a15

SQL> l

  1*select segment_name,bytes/1024/1024||'M' as "size" from dba_segmentswhere segment_name='DAVE' and owner='SYS'

SQL> /

 

SEGMENT_NAME    size

--------------------------------------------------------

DAVE            38M

 

 

--使用默认值创建索引:

SQL> create index idx_dave_id on dave(object_id) ;

Index created.

SQL>

 

--查看默认值:

SQL> select degree from dba_indexes where index_name='IDX_DAVE_ID';

 

DEGREE

----------------------------------------

1

--这里默认为noparallel,即为1.

 

 

--使用并行度为4,对索引进行rebuild

SQL> ater index idx_dave_id rebuildparallel 4;

Index altered.

 

--在次查看索引的并行度:

SQL> select degree from dba_indexes where index_name='IDX_DAVE_ID';

 

DEGREE

----------------------------------------

4

 

注意:

这里变成了4,也就是说启用了索引自己的并行,这样在我们使用索引时会影响执行计划,也会消耗很多的资源。所以,我们需要对这个并行度进行修改,改成noparallel。

 

--修改并行度为noparallel

SQL> alter index idx_dave_id noparallel;

Index altered.

 

--查看并行度:

SQL> select degree from dba_indexes where index_name='IDX_DAVE_ID';

 

DEGREE

----------------------------------------

1

 

这里又变成了1.

 

 

使用并行来处理时,我们可以通过v$px_session 来查看相关的等待事件:

SQL> select a.sql_id,a.event,count(*)from v$session a,v$px_session b where a.sid=b.sid group by a.sql_id,a.event;

 

 

 

关于并行的更多测试参考:

OracleParallel Execution(并行执行)

http://blog.youkuaiyun.com/tianlesoftware/article/details/5854583

 

<think>我们正在讨论Oracle数据库索引创建。根据引用,创建索引的基本语法是: CREATE [UNIQUE] INDEX 索引名 ON 表名(列名1, 列名2, ...) [TABLESPACE 表空间名] [其他可选参数,如NOLOGGING, ONLINE, PARALLEL等]; 其中: - UNIQUE:表示创建唯一索引,确保索引列的值唯一。 - 索引名:自定义的索引名称,通常按照规范命名(例如:表名_列名_IDX)。 - 表名:要创建索引的表。 - 列名:可以是一个或多个列,多列用逗号分隔(即复合索引)。 - TABLESPACE:指定索引存储的表空间,可选。 - 其他可选参数:如NOLOGGING(减少日志生成,加快创建速度但不可恢复)、ONLINE(在线创建,不阻塞DML操作)、PARALLEL(并行创建)等。 注意:创建索引需要权衡,因为索引虽然能提高查询速度,但会降低增删改的速度(需要维护索引)。因此,应选择在查询频繁但更新较少的列上创建索引。 根据引用[3]的例子: CREATE INDEX STUINFO_STUID ON STUINFO(STUID) TABLESPACE USERS; 另外,引用[1]展示了创建唯一索引的例子: create unique index index_name on table(col1,col2,…) tablespace tbs_name [nologging][online][parallel n]; 然后关闭并行:alter index index_name noparallel; 步骤: 1. 确定需要创建索引的表和列,以及索引类型(普通索引还是唯一索引)。 2. 为索引命名(遵循命名规范)。 3. 选择是否指定表空间和其他参数。 4. 执行创建索引的SQL语句。 示例:在表EMPLOYEES的LAST_NAME列上创建普通索引 CREATE INDEX EMP_LAST_NAME_IDX ON EMPLOYEES(LAST_NAME); 示例:在表EMPLOYEES的EMPLOYEE_ID列上创建唯一索引(因为EMPLOYEE_ID通常是唯一的) CREATE UNIQUE INDEX EMP_EMP_ID_PK ON EMPLOYEES(EMPLOYEE_ID); 注意:如果创建唯一索引,则索引列的值必须唯一,否则创建会失败。 另外,引用[4]提醒:创建索引之前需要权衡该字段是否经常发生增删改操作。 如果需要查看索引,可以使用引用[2]中的语句: SELECT * FROM ALL_INDEXES WHERE TABLE_NAME='XXXXX'; 请根据实际需求调整。</think>### Oracle数据库创建索引指南 在Oracle中创建索引是优化查询性能的关键操作,以下是详细步骤和注意事项: #### 1. **基本语法** ```sql CREATE [UNIQUE] INDEX 索引名 ON 表名(列名1, 列名2, ...) [TABLESPACE 表空间名] [其他可选参数]; ``` - **普通索引**:加速查询,允许重复值 ```sql CREATE INDEX emp_dept_idx ON employees(department_id); ``` - **唯一索引**:强制列值唯一性(类似主键约束) ```sql CREATE UNIQUE INDEX emp_email_uniq ON employees(email); ``` #### 2. **关键参数说明** | 参数 | 作用 | 示例 | |------|------|------| | `TABLESPACE` | 指定索引存储位置 | `TABLESPACE users` | | `ONLINE` | 在线创建(不阻塞DML操作) | `CREATE INDEX ... ONLINE` | | `PARALLEL` | 并行加速创建 | `PARALLEL 4`(创建后需关闭) | | `NOLOGGING` | 减少重做日志生成 | `NOLOGGING`(需权衡恢复风险) | #### 3. **复合索引创建** 对多列组合创建索引(列顺序影响查询效率): ```sql CREATE INDEX emp_name_dept_idx ON employees(last_name, department_id); ``` #### 4. **索引重建变更** - **重建索引**(碎片整理): ```sql ALTER INDEX emp_dept_idx REBUILD ONLINE; ``` - **修改参数**(如关闭并行): ```sql ALTER INDEX emp_dept_idx NOPARALLEL; ``` #### 5. **索引管理命令** - 查看索引: ```sql SELECT * FROM ALL_INDEXES WHERE TABLE_NAME = 'EMPLOYEES'; -- Oracle[^2] ``` - 删除索引: ```sql DROP INDEX emp_dept_idx; ``` #### ⚠️ **重要注意事项** 1. **性能权衡**:索引会提升查询速度,但会降低增删改性能(需维护索引结构)[^4] 2. **选择字段原则**: - 在WHERE/JOIN/ORDER BY频繁使用的列创建 - 避免在低区分度(如性别)或频繁更新的列创建 3. **空间规划**:大型索引需预留足够表空间 4. **唯一索引**:需确保数据无重复,否则创建失败 > **示例场景**:为百万级订单表优化日期范围查询 > ```sql > CREATE INDEX orders_date_idx ON orders(order_date) > TABLESPACE idx_data > ONLINE > PARALLEL 8; > ALTER INDEX orders_date_idx NOPARALLEL; -- 创建后关闭并行 > ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值