par*_*rkr 3 database oracle indexing performance
由于特定表上的全表扫描,我的进程表现不佳.我已经计算了统计数据,重建了现有的索引,并尝试为此表添加新索引,但这还没有解决问题.
隐式类型转换可以停止使用索引吗?其他原因呢?全表扫描的成本比索引查找大1000左右.
编辑:
SQL语句:
select unique_key
from src_table
where natural_key1 = :1
and natural_key2 = :2
and natural_key3 = :3;
Run Code Online (Sandbox Code Playgroud)
Java代码(不易修改):
ps.setLong(1, oid);
Run Code Online (Sandbox Code Playgroud)
这与列数据类型:varchar2冲突
Vin*_*rat 12
的隐式转换可以防止使用由优化的指标.考虑:
SQL> CREATE TABLE a (ID VARCHAR2(10) PRIMARY KEY);
Table created
SQL> insert into a select rownum from dual connect by rownum <= 1e6;
1000000 rows inserted
Run Code Online (Sandbox Code Playgroud)
这是一个简单的表,但数据类型不是'正确',即如果你这样查询它将完全扫描:
SQL> select * from a where id = 100;
ID
----------
100
Run Code Online (Sandbox Code Playgroud)
这个查询实际上相当于:
select * from a where to_number(id) = 100;
Run Code Online (Sandbox Code Playgroud)
它因为我们索引id而不能使用索引to_number(id).如果我们想要使用索引,我们必须明确:
select * from a where id = '100';
Run Code Online (Sandbox Code Playgroud)
回复pakr的评论: 关于隐式转换有很多规则.一个好的起点是 文档.除其他外,我们了解到:
在SELECT FROM操作期间,Oracle将列中的数据转换为目标变量的类型.
这意味着当在"WHERE column=variable"子句期间发生隐式转换时,Oracle将转换列的数据类型而不转换变量,从而阻止使用索引.这就是您应该始终使用正确类型的数据类型或显式转换变量的原因.
来自Oracle doc:
Oracle建议您指定显式转换,而不是依赖隐式或自动转换,原因如下:
- 使用显式数据类型转换函数时,SQL语句更容易理解.
- 隐式数据类型转换可能会对性能产生负面影响,尤其是当列值的数据类型转换为常量的数据类型而不是相反时.
- 隐式转换取决于它发生的上下文,并且在每种情况下可能无法以相同的方式工作.例如,从datetime值到VARCHAR2值的隐式转换可能会返回意外的年份,具体取决于NLS_DATE_FORMAT参数的值.
- 隐式转换的算法可能会在软件版本和Oracle产品之间发生变化.显式转换的行为更具可预测性.
让你条件sargable,即将字段本身与恒定条件进行比较.
这是不好的:
SELECT *
FROM mytable
WHERE TRUNC(date) = TO_DATE('2009.07.21')
Run Code Online (Sandbox Code Playgroud)
,因为它无法使用索引.Oracle无法反转TRUNC()函数来获取范围界限.
这很好:
SELECT *
FROM mytable
WHERE date >= TO_DATE('2009.07.21')
AND date < TO_DATE('2009.07.22')
Run Code Online (Sandbox Code Playgroud)
要摆脱隐式转换,请使用显式转换:
这是不好的:
SELECT *
FROM mytable
WHERE guid = '794AB5396AE5473DA75A9BF8C4AA1F74'
-- This uses implicit conversion. In fact this is RAWTOHEX(guid) = '794AB5396AE5473DA75A9BF8C4AA1F74'
Run Code Online (Sandbox Code Playgroud)
这很好:
SELECT *
FROM mytable
WHERE guid = HEXTORAW('794AB5396AE5473DA75A9BF8C4AA1F74')
Run Code Online (Sandbox Code Playgroud)
更新:
这个查询:
SELECT unique_key
FROM src_table
WHERE natural_key1 = :1
AND natural_key2 = :2
AND natural_key3 = :3
Run Code Online (Sandbox Code Playgroud)
在很大程度上取决于你的领域的类型.
将变量显式转换为字段类型,就像从字符串中转换一样.
| 归档时间: |
|
| 查看次数: |
8596 次 |
| 最近记录: |