我有一个没有意义的计划的简单 Oracle 查询。
SELECT
u.custid AS "custid",
l.listid AS "listid"
FROM
users u
INNER JOIN lists l ON u.custid = l.custid
这是自动跟踪解释告诉我的计划
------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1468K| 29M| | 11548 (1)| 00:00:01 |
|* 1 | HASH JOIN | | 1468K| 29M| 7104K| 11548 (1)| 00:00:01 |
| 2 | INDEX FAST FULL SCAN| USERS_PK | 404K| 2367K| | 266 (2)| 00:00:01 |
|* 3 | TABLE ACCESS FULL | LISTS | 1416K| 20M| | 9110 (1)| 00:00:01 |
------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("U"."CUSTID"="L"."CUSTID")
3 - filter(TRUNC("SORT_TYPE")>=1 AND TRUNC("SORT_TYPE")<=16)
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- this is an adaptive plan
- 1 Sql Plan Directive used for this statement
我关心的是谓词 3. sort_type
没有出现在查询中,并且根本没有被索引。在我看来,sort_type
根本不应该参与这个查询。
有一个限制:(是的,我知道我们可能是整数而不是数字)lists.sort_type
sort_type
sort_type NUMBER DEFAULT 2 NOT NULL,
CONSTRAINT lists_sort_type CHECK ( sort_type BETWEEN 1 AND 16 AND TRUNC(sort_type) = sort_type )
在我看来,那个过滤器sort_type
基本上是一个重言式。lists
由于该约束,其中的每一行都必须通过该过滤器。
如果我放弃约束,过滤器将不再显示在计划中,并且估计成本会下降一点。如果我重新添加约束,计划将再次使用过滤器。一种或另一种方式的执行速度没有显着差异。
我很担心,因为我在一个更大、更复杂的查询中发现了这个过滤器,我试图从几分钟的运行时间优化下来。
为什么 Oracle 添加该过滤器,这是一个问题和/或指向另一个问题?
编辑:如果我将约束更改sort_type
为没有TRUNC
零件,过滤器就会消失。如果我将约束分成两个不同的约束,过滤器就会回来。