sql - 我怎样才能使用这种索引?
问题描述
我正在尝试使用一种索引但不起作用。也许你可以帮助我意识到我做错了什么。
这是我的表的定义:
CREATE TABLE "TIR"."INT07NCMP"(
"INT07_CORRELATIVO" NUMBER(10) NOT NULL ENABLE,
"INT07_CENTRO" VARCHAR2(4 BYTE) NOT NULL ENABLE,
"INT07_CODCOMPONENTE" VARCHAR2(18 BYTE) NOT NULL ENABLE,
"INT07_ALMCOMPONENTE" VARCHAR2(4 BYTE) NOT NULL ENABLE,
"INT07_CANCOMPONENTE" NUMBER(13,3),
"INT07_UNICOMPONENTE" VARCHAR2(3 BYTE),
"INT07_CODPORTADOR" VARCHAR2(18 BYTE) NOT NULL ENABLE,
"INT07_ALMPORTADOR" VARCHAR2(4 BYTE) NOT NULL ENABLE,
"INT07_CANPORTADOR" NUMBER(13,3),
"INT07_UNIPORTADOR" VARCHAR2(3 BYTE),
"INT07_ALMDESTINO" VARCHAR2(4 BYTE) NOT NULL ENABLE,
"INT07_FECINICIO" VARCHAR2(10 BYTE) NOT NULL ENABLE,
"INT07_HORINICIO" VARCHAR2(8 BYTE) NOT NULL ENABLE,
"INT07_FECTERMINO" VARCHAR2(10 BYTE) NOT NULL ENABLE,
"INT07_HORTERMINO" VARCHAR2(8 BYTE) NOT NULL ENABLE,
"INT07_ESTPOCH" VARCHAR2(1 BYTE),
"INT07_TMPPOCH" TIMESTAMP (6),
"INT07_ESTSAP" VARCHAR2(1 BYTE),
"INT07_TMPSAP" TIMESTAMP (6),
"INT07_TIMESTAMP" TIMESTAMP (6) NOT NULL ENABLE,
CONSTRAINT "INT07NCMP_PK" PRIMARY KEY ("INT07_CORRELATIVO"),
CONSTRAINT "INT07NCMP_UK1" UNIQUE (
"INT07_CENTRO", "INT07_CODCOMPONENTE", "INT07_ALMCOMPONENTE", "INT07_CODPORTADOR", "INT07_ALMPORTADOR",
"INT07_FECINICIO", "INT07_HORINICIO", "INT07_FECTERMINO", "INT07_HORTERMINO"
)
);
这是我创建的索引:
CREATE INDEX "TIR"."INT07NCMP_IDX1" ON "TIR"."INT07NCMP" ("INT07_CENTRO", "INT07_ESTPOCH");
CREATE INDEX "TIR"."INT07NCMP_IDX2" ON "TIR"."INT07NCMP" ("INT07_CENTRO", "INT07_ESTSAP");
CREATE INDEX "TIR"."INT07NCMP_IDX3" ON "TIR"."INT07NCMP" ("INT07_CENTRO", "INT07_CORRELATIVO", "INT07_FECINICIO", "INT07_HORINICIO", "INT07_FECTERMINO", "INT07_HORTERMINO");
使用“解释计划”我对索引 1 和 2 很好,但对索引 3 没有。例如我正在尝试这个查询:
SELECT * FROM INT07NCMP
WHERE INT07_CENTRO = '7100'
AND INT07_CORRELATIVO > 0
这就是答案:
Plan hash value: 2810525850
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9770 | 1450K| 1 (0)| 00:00:01 |
|* 1 | TABLE ACCESS BY INDEX ROWID| INT07NCMP | 9770 | 1450K| 1 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | INT07NCMP_IDX1 | 39 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("INT07_CORRELATIVO">0)
2 - access("INT07_CENTRO"='7100')
Note
-----
- dynamic sampling used for this statement (level=2)
因此,如您所见,只使用了 IDX1,我希望使用 IDX3,因为我使用“INT07_CENTRO”然后“INT07_CORRELATIVO”进行过滤,就像索引定义的顺序一样。如果我尝试放置更多过滤器(IDX3 的所有列)它也不起作用。
这有什么提示吗?
谢谢
解决方案
假设你有很好的统计数据。user_tables 和 user_indexes 中的 num_rows。
给出那个,在这些情况下最好的方法是简单地相信 db 正在做出正确的决定。它考虑了很多方面,例如统计物理组织等。因此,根据数据规则创建索引并创建查询,然后信任数据库。
在极少数情况下,您可能必须强制查询。您可以使用提示。但在这种情况下,除非它产生了我怀疑的巨大差异 - 只需在第一个索引的末尾添加 correlatoivo 就可以了。因为保存不会来自对此的范围扫描,但那个 oracle 不必去数据库表来获取它并且索引扫描就足够了
推荐阅读
- c++ - 如何将 node*create 语句与链表一起使用?
- java - 循环格式化输出的问题
- java - 在单个活动中使用多个按钮
- java - Java类关联中的“包含”和“包含”有什么区别
- php - SQL 更新不适用于 AJAX
- ios - 迁移到 Xcode 10.2 后,collectionView didSelectItemAtIndexPath 停止工作
- python - 如果有相同的值,如何根据循环打印唯一代码?
- android-emulator - 在 Ubuntu 18.04 上运行 Android 模拟器时看到“无法 statvfs() 路径:没有这样的文件或目录”
- python - 如何使用python单独替换字符串中的第一个字符?
- javascript - 模态关闭后Jquery不重新加载div