[英]Improve join query in Oracle
我有一個需要17秒才能執行的查詢。 我已經在FIPS,STR_DT,END_DT上應用了索引,但仍然需要時間。 關於如何提高性能的任何建議?
我的查詢:
SELECT /*+ALL_ROWS*/ K_LF_SVA_VA.NEXTVAL VAL_REC_ID, a.REC_ID,
b.VID,
1 VA_SEQ,
51 VA_VALUE_DATATYPE,
b.VALUE VAL_NUM,
SYSDATE CREATED_DATE,
SYSDATE UPDATED_DATE
FROM CTY_REC a JOIN FIPS_CONS b
ON a.FIPS=b.FIPS AND a.STR_DT=b.STR_DT AND a.END_DT=b.END_DT;
DESC CTY_REC;
Name Null Type
------------------- ---- -------------
REC_ID NUMBER(38)
DATA_SOURCE_DATE DATE
STR_DT DATE
END_DT DATE
VID_RECSET_ID NUMBER
VID_VALSET_ID NUMBER
FIPS VARCHAR2(255)
DESC FIPS_CONS;
Name Null Type
------------- -------- -------------
STR_DT DATE
END_DT DATE
FIPS VARCHAR2(255)
VARIABLE VARCHAR2(515)
VALUE NUMBER
VID NOT NULL NUMBER
解釋計划:
Plan hash value: 919279614
--------------------------------------------------------------
| Id | Operation | Name |
--------------------------------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | SEQUENCE | K_VAL |
| 2 | HASH JOIN | |
| 3 | TABLE ACCESS FULL| CTY_REC |
| 4 | TABLE ACCESS FULL| FIPS_CONS |
--------------------------------------------------------------
我添加了表的描述並解釋了我的查詢計划。
從表面上看,如果沒有關於您正在使用的序列的配置,每個表中的行數以及從查詢中投射的總行數的信息,您的執行計划可能是最多的有效的一個返回所有行。
優化器顯然認為索引不會對性能有所幫助,當您優化所有行而不是第一行時,這通常更有可能。 基於索引的訪問是單個塊,一次一行,因此可以比每個塊的多塊完全掃描更慢。
Oracle正在使用的散列連接是一種非常有效的連接數據集的方法。 除非散列表太大以至於溢出到磁盤,否則總成本僅略高於兩個表的完全掃描。 我們需要有關執行的更詳細統計信息,以便能夠判斷散列表是否溢出到磁盤,如果是解決方案可能只是修改內存管理,而不是索引。
如果序列的緩存值非常低且記錄數量很高,那么可能還會阻止SQL執行的是調用該序列。 需要更多信息 - 如果您需要為每一行生成順序標識符,那么您可以使用ROWNUM。
這基本上是您的查詢:
SELECT . . .
FROM CTY_REC a JOIN
FIPS_CONS b
ON a.FIPS = b.FIPS AND a.STR_DT = b.STR_DT AND a.END_DT = b.END_DT;
您希望在兩個表上都有(FIPS, STR_DT, END_DT)
復合索引:
create index idx_cty_rec_3 on cty_rec(FIPS, STR_DT, END_DT);
create index idx_fipx_con_3 on cty_rec(FIPS, STR_DT, END_DT);
實際上,只有一個可能是必要的,但兩者都為優化器提供了更多選擇來改進查詢。
你應該在表上至少有這兩個索引:
相反,它仍然可以加速覆蓋索引:
如果您希望驅動優化器使用索引,
將/*+ all_rows */
替換為/*+ first_rows */
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.