index 和 index_desc hints的一点有意思的区别

本文介绍在Oracle数据库中如何使用索引优化DELETE语句的执行计划,通过两种不同方式指定索引,实现对特定范围记录的有效删除,并展示了相关执行计划。

2 - access("T1"."OBJECT_ID">=6361 AND "T1"."OBJECT_ID"<=6400)

2 - access("T1"."OBJECT_ID">=6361 AND "T1"."OBJECT_ID"<=6400)
filter("T1"."OBJECT_ID"<=6400 AND "T1"."OBJECT_ID">=6361)


SQL>create table t1 as select * from user_objects;

SQL>create index t1_object_id_ind on t1(object_id) tablespace users;


SQL>explain plan for
2 delete /*+ index(t1 t1_object_id_ind)*/from t1 where object_id>=6361 and object_id<=6400;

Explained.

SQL>@?/rdbms/admin/utlxplp

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------

--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
--------------------------------------------------------------------------
| 0 | DELETE STATEMENT | | 4 | 52 | 2 |
| 1 | DELETE | T1 | | | |
|* 2 | INDEX RANGE SCAN | T1_OBJECT_ID_IND | 4 | 52 | 2 |
--------------------------------------------------------------------------

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

2 - access("T1"."OBJECT_ID">=6361 AND "T1"."OBJECT_ID"<=6400)
Note: cpu costing is off

15 rows selected.

SQL>explain plan for
2 delete /*+ index_desc(t1 t1_object_id_ind)*/from t1 where object_id>=6361 and object_id<=6400;

Explained.

SQL>@?/rdbms/admin/utlxplp

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
----------------------------------------------------------------------------------
| 0 | DELETE STATEMENT | | 4 | 52 | 2 |
| 1 | DELETE | T1 | | | |
|* 2 | INDEX RANGE SCAN DESCENDING| T1_OBJECT_ID_IND | 4 | 52 | 2 |
----------------------------------------------------------------------------------

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

2 - access("T1"."OBJECT_ID">=6361 AND "T1"."OBJECT_ID"<=6400)
filter("T1"."OBJECT_ID"<=6400 AND "T1"."OBJECT_ID">=6361)


Note: cpu costing is off

16 rows selected.

SQL>[@more@]

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7312700/viewspace-1004727/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/7312700/viewspace-1004727/

<think>我们参考上述引用,特别是引用[3]引用[4],来回答用户关于`wal_log_hints`参数的问题。用户问题:PostgreSQLwal_log_hints配置及作用回答结构:1.参数的作用2.参数的适用场景3.配置方法及注意事项4.相关影响根据引用[4]:-`wal_level`控制写入WAL的信息量,默认是`minimal`。-`wal_log_hints`参数只能在服务器启动时设置,默认值为`off`。-当设置为`on`时,在检查点之后第一次更改页面时,即使更改的是提示位(hintbits),也会将整个磁盘页写入WAL。-提示位是页面上的一种标志,用于表示事务提交状态等信息,通常是非关键性的(因为事务提交状态也记录在事务提交日志中)。-如果数据库初始化时使用了数据校验(`--data-checksums`),那么提示位更新总是被记录在WAL中,因此不需要开启`wal_log_hints`。根据引用[3]:-`pg_rewind`工具用于在主从时间线发生分歧后重新同步从库,而不需要完全重新克隆。-`pg_rewind`要求:目标服务器在`postgresql.conf`中允许`wal_log_hints`(默认关闭)或者初始化时启用了数据校验,并且`full_page_writes`必须为`on`(默认开启)。因此,`wal_log_hints`的主要作用是在未使用数据校验的情况下,为`pg_rewind`等工具提供支持,通过记录整个页面的内容,使得这些工具能够检测修复因时间线分歧导致的页面不一致。配置方法:1.修改`postgresql.conf`文件,设置:```wal_log_hints=on```2.此参数修改后需要重启PostgreSQL实例才能生效。注意事项:-如果数据库实例在初始化时使用了`--data-checksums`选项(即启用了数据页校验),则无需设置`wal_log_hints=on`,因为此时提示位更新已经会记录到WAL中。-开启此参数可能会增加WAL日志量,因为每次检查点后第一次修改页面时,即使只修改了提示位,也会写入整个页面(通常4KB或8KB)。因此,在频繁更新的数据库中,可能会对性能产生一定影响。适用场景:-当需要使用`pg_rewind`工具来重新同步从库,且数据库初始化时没有启用数据校验时,需要开启此参数。-某些特定的工具(如某些备份工具)可能也需要开启此参数。总结:-作用:支持在没有启用数据校验的情况下,通过记录整个页面来使`pg_rewind`等工具正常工作。-配置:在配置文件中设置并重启。-注意:已开启数据校验则无需设置,否则可能增加WAL量。最后,我们可以根据以上内容生成相关问题。</think> ### PostgreSQL `wal_log_hints` 配置及作用详解 #### 1. **参数作用** `wal_log_hints` 控制**提示位(hint bits)变更的 WAL 记录行为**: - 当设置为 `on` 时,在**检查点后首次修改页面时**(包括非关键性的提示位变更),PostgreSQL 会将**整个磁盘页内容写入 WAL**(通常为 4KB/8KB)[^4]。 - 若数据库启用了**数据校验**(`initdb --data-checksums`),无论此参数是否开启,提示位变更始终记录在 WAL 中[^4]。 - 核心目的:支持 `pg_rewind` 等工具**高效修复主从不一致**(仅同步差异文件)[^3]。 #### 2. **适用场景** - ✅ **主从修复工具需求**:使用 `pg_rewind` 重新同步分叉的时间线(如主库切换后旧主库重新接入集群)时,必须开启此参数或启用数据校验[^3]。 - ❌ **常规流复制**:基础流复制或 WAL 归档(`wal_level=replica/archive`)无需开启此参数。 #### 3. **配置方法** 在 `postgresql.conf` 中添加并重启实例: ```ini wal_log_hints = on # 默认值为 off ``` **注意事项**: - ⚠️ 必须**重启 PostgreSQL 实例**生效(无法动态修改)[^4]。 - ⚙️ **数据校验优化**:若已通过 `initdb --data-checksums` 初始化数据库,可跳过此参数(校验强制记录提示位)[^4]。 - 📏 **WAL 影响**:可能增加 WAL 日志量(需额外记录全页),但确保关键修复工具的可用性[^4]。 #### 4. **与相关参数的关系** - **`wal_level`**:需至少设为 `replica` 或更高(如 `hot_standby`)以使 `wal_log_hints` 生效[^4]。 - **`full_page_writes`**:必须为 `on`(默认值),否则 `pg_rewind` 无法工作[^3]。 - **`wal_keep_segments`**:建议保留足够 WAL 段(如 `1000`),避免因清理导致修复失败[^2]。 > **典型场景配置示例**(主库切换后旧主库修复): > ```bash > # 在旧主库执行 pg_rewind 前检查配置 > pg_rewind --target-pgdata=/data/postgresql \ > --source-server="host=new_primary port=5432" > ``` --- ### 相关技术原理图解 ```mermaid graph TD A[检查点完成] --> B[首次修改数据页] B --> C{wal_log_hints=on?} C -->|Yes| D[写入整个页到 WAL] C -->|No| E[仅写入变更部分] F[启用数据校验] --> D # 强制记录全页 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值