【发布时间】:2015-01-25 21:28:46
【问题描述】:
由于“order by”,以下查询的性能很差。我的目标是只获得结果集的一小部分(例如,使用 ROWNUM)。但是,当我添加“order by”时,它会遍历整个结果集,为每条记录执行索引查找,这使得它非常慢。当我将结果集限制为例如 1000 条记录时,如果不进行排序,查询的速度大约快 100 倍。
查询:
SELECT text_field
from mytable where
contains(text_field,'ABC', 1)>0
order by another_field;
这就是我创建索引的方式:
CREATE INDEX myindex ON mytable (text_field) INDEXTYPE IS ctxsys.context FILTER BY another_field
执行计划:
---------------------------------------------------------------
| Id | Operation | Name |
---------------------------------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | SORT ORDER BY | |
| 2 | TABLE ACCESS BY INDEX ROWID| MYTABLE |
|* 3 | DOMAIN INDEX | MYINDEX |
---------------------------------------------------------------
我也用 CTXCAT 代替了 CONTEXT,没有任何改进。我认为问题是,当我想要对结果进行排序(仅前 1000 个)时,它会为“整个”结果集中的每条记录执行索引查找。有没有办法避免这种情况?
谢谢。
【问题讨论】:
-
抱歉,上面文本中执行计划部分的格式似乎有问题。
-
是检索所有数据快 100 倍,还是仅检索第一批/页的结果?当然不能帮助您调整它的顺序,但可能有助于理解差异。
-
只是结果的第一页。但是,当我使用排序时,它会遍历所有结果,即使我只请求第一页,这也是让它变慢的原因。因此,我试图找到一种创建索引的方法,以便在要求排序时不必遍历整个结果集即可返回第一页。
-
限制为 1000 行的查询在哪里?您是否将 rownum 检查应用于作为子查询显示的查询?请将该代码及其解释计划添加到问题中。它应该在计划中加入一个“计数停止键”步骤。
-
我实际上是从 SAS 内部执行“sql pass-through”的。我使用“outobs”参数。但是,我认为这类似于 ROWNUM。
标签: oracle performance sorting text indexing