簡體   English   中英

改進Oracle中的連接查詢

[英]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);

實際上,只有一個可能是必要的,但兩者都為優化器提供了更多選擇來改進查詢。

你應該在表上至少有這兩個索引:

  • CTY_REC(FIPS,STR_DT,END_DT)
  • FIPS_CONS(FIPS,STR_DT,END_DT)

相反,它仍然可以加速覆蓋索引:

  • CTY_REC(FIPS,STR_DT,END_DT,REC_ID)
  • FIPS_CONS(FIPS,STR_DT,END_DT,VALUE,VID)

如果您希望驅動優化器使用索引,
/*+ all_rows */替換為/*+ first_rows */

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM