Loc*_*ock 8 oracle indexing performance join query-optimization
我很擅长索引和解释计划,所以请耐心等待!我正在尝试调整查询,但我遇到了问题.
我有两张桌子:
SKU
------
SKUIDX (Unique index)
CLRIDX (Index)
..
..
IMPCOST_CLR
-----------
ICCIDX (Unique index)
CLRIDX (Index)
...
..
Run Code Online (Sandbox Code Playgroud)
当我这样做时select * from SKU where clridx = 122,我可以看到它正在使用解释计划中的索引(它表示TABLE ACCESS .. INDEX,它表示OBJECT_NAME下的索引名称,选项是RANGE SCAN).
现在,当我尝试加入同一个字段时,它似乎没有使用索引(它表示TABLE ACCESS .. HASH JOIN和选项下,它表示FULL).
我应该寻找什么来试图看看为什么它没有使用索引?对不起,我不确定要输入什么命令来显示,所以如果您需要更多信息,请告诉我.
示例:
第一个查询:
SELECT
*
FROM
AP21.SKU
WHERE
CLRIDX = 100
Run Code Online (Sandbox Code Playgroud)

第二个查询:
SELECT
*
FROM
AP21.IMPCOST_CLR
WHERE
CLRIDX = 100
Run Code Online (Sandbox Code Playgroud)

第三个查询:
SELECT
*
FROM
AP21.SKU
INNER JOIN
AP21.IMPCOST_CLR ON
IMPCOST_CLR.CLRIDX = SKU.CLRIDX
Run Code Online (Sandbox Code Playgroud)

APC*_*APC 19
看看这个查询:
SELECT
*
FROM
AP21.SKU
INNER JOIN
AP21.IMPCOST_CLR ON
IMPCOST_CLR.CLRIDX = SKU.CLRIDX
Run Code Online (Sandbox Code Playgroud)
它没有额外的谓词.因此,您将SKU中的所有行连接到IMPCOST_CLR中的所有行.此外,您正在从两个表中选择所有列.
这意味着Oracle必须读取两个表的全部内容.最有效的方法是使用全表扫描,挖掘多块读取中的所有行,并使用散列来匹配连接的值.
基本上,它是一个set操作,这是SQL做得很好,而索引读取更多RBAR.现在,如果您更改了第三个查询以包含其他谓词,例如
WHERE SKU.CLRIDX = 100
Run Code Online (Sandbox Code Playgroud)
您很可能会看到访问路径恢复为INDEX RANGE SCAN.因为您只选择了少数几行,所以索引读取再次是更有效的路径.
"我试图调整的查询是数百个更长的时间,但要将其分解并逐步进行!"
这是一种很好的技术,但您需要了解Oracle Optimzer的工作原理.解释计划中有很多信息. 了解更多. 注意Rows每个步骤的列中的值.这告诉您Optimizer期望从操作中获得多少行.与第三个查询相比,前两个查询将看到非常不同的值.
现在,当我尝试加入同一个字段时,它似乎没有使用索引(它表示TABLE ACCESS .. HASH JOIN和选项下,它表示FULL).
这是因为HASH JOIN不对连接谓词使用(需要)索引:
http://use-the-index-luke.com/sql/join/hash-join-partial-objects
| 归档时间: |
|
| 查看次数: |
27446 次 |
| 最近记录: |