1.transaction_isolation=READ-COMMITED
读已提交:只能读取其它事务已提交的数据,避免脏读;
行级锁:仅在查询执行期间锁定读取的行,其他事务可随时修改未被锁定的行;
|
隔离级别 |
脏读 |
不可重复读 |
幻读 |
锁开销 |
并发性能 |
|
READ-UNCOMMITTED |
✅ |
✅ |
✅ |
最小 |
最高 |
|
READ-COMMITTED |
❌ |
✅ |
✅ |
较小 |
高 |
|
REPEATABLE-READ |
❌ |
❌ |
✅ |
中等 |
中 |
|
SERIALIZABLE |
❌ |
❌ |
❌ |
最大 |
最低 |
需严格一致性时使用REPEATABLE-READ(锁行为:查询时锁定读取的行范围,其他事务无法修改或插入锁定范围内的数据。)。
2.ob_trx_timeout=1000000000/ob_query_timeout=12000000000
ob_trx_timeout 参数:默认1000s
- 单个事务的最长执行时间(包括所有 SQL 语句和中间操作)
- 超时后事务会自动回滚,释放持有的锁资源
-- 会话级别(当前连接有效)
SET ob_trx_timeout = 1000000000; -- 单位:微秒
-- 全局级别(需管理员权限)
ALTER SYSTEM SET ob_trx_timeout = 1000000000;
ob_query_timeout参数:默认12000 s
- 单个 SQL 查询(包括 SELECT、INSERT、UPDATE、DELETE 等)的最长执行时间。
- 超时后查询会被终止,但事务不会回滚(除非查询是事务的最后一个操作)。
事务超时 ≤ 查询超时:通常建议ob_trx_timeout小于ob_query_timeout,确保事务整体执行时间不会超过单个查询的限制。
3.ob_enable_index_direct_select=ON
索引直接访问:当查询仅需索引列数据时,OceanBase 可直接通过二级索引返回结果,无需回表访问主表。
参数效果:
ON(默认):启用优化,优先使用索引直接访问。
OFF:禁用优化,强制回表,即使索引包含所有需要的列。
启用条件:
查询列必须全部包含在二级索引中。
索引设计需覆盖业务常见查询。
假设你有一个员工表 employees,包含以下字段:
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(100),
department VARCHAR(50),
salary DECIMAL(10, 2),
age INT,
INDEX idx_dept_salary (department, salary) -- 二级索引:包含 department 和 salary
);
示例 1:启用索引直接访问(覆盖索引)
查询:
SELECT department, salary
FROM employees
WHERE department = '技术部';
执行流程:
扫描索引:优化器直接扫描 idx_dept_salary 索引(无需访问主表)。
过滤数据:通过索引中的 department 列过滤出 技术部 的记录。
直接返回:查询仅需要 department 和 salary,而这两列恰好都在索引中,因此无需回表,直接从索引返回结果。
执行计划:
plaintext
|ID|OPERATOR |NAME |EST. ROWS|COST |
|---|---------------|-------------------|---------|------|
|0 |TABLE SCAN |employees(idx_dept_salary)|100 |1585 |
关键点:TABLE SCAN 后显示的是索引名(idx_dept_salary),表示仅扫描索引。
示例 2:禁用索引直接访问(强制回表)
查询相同:
SELECT department, salary
FROM employees
WHERE department = '技术部'
执行流程:
扫描索引:扫描 idx_dept_salary 索引,找到 department = '技术部' 的记录。
回表:对于每条匹配的记录,根据索引中的主键(id)回主表查询 department 和 salary(即使索引中已有这两列)。
返回结果:从主表获取数据后返回。
执行计划:
plaintext
|ID|OPERATOR |NAME |EST. ROWS|COST |
|---|---------------|-------------------|---------|------|
|0 |TABLE SCAN |employees |100 |2000 |
关键点:TABLE SCAN 后显示的是表名(employees),表示需要访问主表。
对比说明
|
场景 |
索引直接访问(ON) |
强制回表(OFF) |
|
数据访问 |
仅扫描索引 |
扫描索引 + 回表访问主表 |
|
IO 次数 |
少(仅索引数据) |
多(索引 + 主表) |
|
适用条件 |
查询列完全包含在索引中 |
无限制 |
|
性能 |
通常快 5-10 倍(取决于数据量) |
慢(尤其在大数据量下 |
示例 3:查询列不在索引中(必须回表)
查询:
SELECT department, salary, age -- 新增 age 列(不在索引中)
FROM employees
WHERE department = '技术部';
执行流程:
扫描索引:扫描 idx_dept_salary 索引,找到 department = '技术部' 的记录。
回表:由于 age 不在索引中,必须回主表获取该列数据。
返回结果:合并索引和主表的数据后返回。
关键点:
无论参数是否启用,只要查询列不完全在索引中,都需要回表。
510

被折叠的 条评论
为什么被折叠?



