【发布时间】:2015-03-24 10:23:54
【问题描述】:
这是我的几百万行的表格:
CREATE TABLE "TEST_TABLE"
( "ID" NUMBER(*,0),
"TYPE" NUMBER(*,0),
"NAME" VARCHAR2(10 BYTE)
);
还有几个索引:
CREATE INDEX TEST_INDEX_T_N ON TEST_TABLE (TYPE, NAME);
CREATE INDEX TEST_INDEX_T_I ON TEST_TABLE (TYPE, ID);
以下查询时
SELECT * FROM TEST_TABLE WHERE TYPE = 1 ORDER BY ID
我有以下计划
| 0 | SELECT STATEMENT | | 886K| 21M| 2192 (1)| 00:00:27 |
|* 1 | INDEX RANGE SCAN| TEST_INDEX_T_I | 886K| 21M| 2192 (1)| 00:00:27 |
但是,如果出现以下情况:
SELECT NAME FROM TEST_TABLE WHERE TYPE = 1 ORDER BY NAME;
我明白了
| 0 | SELECT STATEMENT | | 886K| 16M| | 7826 (1)| 00:01:34 |
| 1 | SORT ORDER BY | | 886K| 16M| 23M| 7826 (1)| 00:01:34 |
|* 2 | INDEX RANGE SCAN| TEST_INDEX_T_N | 886K| 16M| | 2415 (1)| 00:00:29 |
所以,据我了解,oracle 不使用索引对 varchar 列进行排序(因为说明计划中有额外的 SORT ORDER BY 操作),但在 INT 或 DATE 类型的情况下一切都很好。如何“使用索引进行排序”varchar 列?
【问题讨论】:
-
为什么要 Oracle 使用索引进行排序?当 Oracle 必须对结果集进行排序时,内存或 TEMP 表空间中的所有内容都已可用。无需从光盘中读取任何其他内容。
-
请注意,您认为它不适用于 varchars 的建议是不正确的。我试图重现你的情况(但是在更小的集合上,比如 100k 行),对于按 NAME 排序的第二个查询,我正在为第一个查询制定像你一样的计划,即只有 select 语句和 INDEX RANGE SCAN by test_index_t_n跨度>
-
@Wernfried 因为它要快得多。在以下查询 SELECT * FROM TEST_TABLE WHERE TYPE = 1 ORDER BY ID 的情况下,在我的特定情况下(在开发人员机器上,表中有 10.000.000 条记录,结果集中有 1000.000 条记录),速度要快 50 倍。
-
@Mina 你能展示你的初始化脚本吗?
-
@san DDL 与您的完全一样,然后我用示例数据填充了表格,其中前两列是随机数 1-500,第三列是五个预定义字符串之一。肯定它不符合您的情况,但只是为了证明执行计划非常依赖数据。
标签: oracle indexing sql-order-by