【发布时间】:2021-02-15 07:03:19
【问题描述】:
我有一个 Oracle 数据库,其中一个主表包含 9 000 000 行,第二个包含 19 000 000 行。
当我这样做时:
SELECT *
FROM main m
INNER JOIN second s ON m.id = s.fk_id AND s.cd = 'E' AND s.line = 1
获取结果的第一部分需要 45 秒,即使所有索引都在下面:
CREATE INDEX IDX_1 ON SECOND (LINE, CD, FK_ID, ID);
CREATE INDEX IDX_1 ON SECOND (LINE, CD);
MAIN (ID) AS PRIMARY KEY
知道如何更快地做到这一点吗?我尝试了一些索引,重建但总是需要 45 秒
这是执行计划:
------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 8850631 | 2133002071 | 696494 | 00:00:28 |
| * 1 | HASH JOIN | | 8850631 | 2133002071 | 696494 | 00:00:28 |
| * 2 | TABLE ACCESS FULL | SECOND | 8850631 | 646096063 | 143512 | 00:00:06 |
| 3 | TABLE ACCESS FULL | MAIN | 9227624 | 1550240832 | 153363 | 00:00:06 |
------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 1 - access("M"."ID"="S"."FK_ID")
* 2 - filter("S"."CD"='D' AND "S"."LINE"=1)
谢谢
【问题讨论】:
-
您的数据是否可以为这四列而不是当前索引添加唯一(或主)键?如果可能,您可能会获得性能提升。
-
发布查询计划。您的谓词的选择性如何?
-
好吧,如果只有一个表被索引,您将不得不
full table scan另一个 - 这解释了我们的 45 秒。如果您想快速查看第一条记录,您必须在second表上建立索引才能访问s.cd = 'E' AND s.line = 1,并在main上建立索引才能访问连接列。请参阅here 您应提供的其他信息。 -
重要提示 - 有多少行匹配谓词
s.cd = 'E' AND s.line = 1?您预计连接将返回多少行? -
@MarmiteBomber 不幸的是我同意。