Oracle還是比較常用的,於是我研究了一下Oracle INDEX提示,當使用hints時,在某些情況下,為了確保讓優化器產生最優的執行計劃,我們可能指定全套的hints,在這裡拿出來和大家分享一下,希望對大家有用。
例如,如果有一個復雜的查詢,包含多個表連接,如果你只為某個表指定了Oracle INDEX提示(指示存取路徑在該表上使用索引),優化器需要來決定其它應該使用的訪問路徑和相應的連接方法。因此,即使你給出了一個Oracle INDEX提示,優化器可能覺得沒有必要使用該提示。這是由於我們讓優化器選擇了其它連接方法和存取路徑,而基於這些連接方法和存取路徑,優化器認為用戶給出的Oracle INDEX提示無用。為了防止這種情況,我們要使用全套的hints,如:不但指定要使用的索引,而且也指定連接的方法與連接的順序等。
下面是一個使用全套hints的例子,ORDERED提示指出了連接的順序,而且為不同的表指定了連接方法:
- SELECT /*+ ORDERED INDEX (b, jl_br_balances_n1) USE_NL (j b)
- USE_NL (glcc glf) USE_MERGE (gp gsb) */
- b.application_id, b.set_of_books_id ,
- b.personnel_id, p.vendor_id Personnel,
- p.segment1 PersonnelNumber, p.vendor_name Name
- FROM jl_br_journals j, jl_br_balances b,
- gl_code_combinations glcc, fnd_flex_values_vl glf,
- gl_periods gp, gl_sets_of_books gsb, po_vendors p
- WHERE ...
指示優化器的方法與目標的hints:
- ALL_ROWS -- 基於代價的優化器,以吞吐量為目標
- FIRST_ROWS(n) -- 基於代價的優化器,以響應時間為目標
- CHOOSE -- 根據是否有統計信息,選擇不同的優化器
- RULE -- 使用基於規則的優化器
例子:
- SELECT /*+ FIRST_ROWS(10) */ employee_id, last_name, salary, job_id
- FROM employees
- WHERE department_id = 20;
- SELECT /*+ CHOOSE */ employee_id, last_name, salary, job_id
- FROM employees
- WHERE employee_id = 7566;
- SELECT /*+ RULE */ employee_id, last_name, salary, job_id
- FROM employees
- WHERE employee_id = 7566;