我有以下簡單的動態選擇查詢甲骨文簡單的SELECT查詢優化
Select RELATIONSHIP
from DIME_MASTER
WHERE CIN=? AND SSN=? AND ACCOUNT_NUMBER=?
表有1083701條記錄。這個查詢需要11到12秒執行,這很昂貴。 DIME_MASTER表具有ACCOUNT,CARD_NUMBER INDEXES。請幫助我優化此查詢,以便查詢執行時間小於秒。
我有以下簡單的動態選擇查詢甲骨文簡單的SELECT查詢優化
Select RELATIONSHIP
from DIME_MASTER
WHERE CIN=? AND SSN=? AND ACCOUNT_NUMBER=?
表有1083701條記錄。這個查詢需要11到12秒執行,這很昂貴。 DIME_MASTER表具有ACCOUNT,CARD_NUMBER INDEXES。請幫助我優化此查詢,以便查詢執行時間小於秒。
看看該謂語信息:
--------------------------------------
1 - filter(TO_NUMBER("DIME_MASTER"."SSN")=226550956
AND TO_NUMBER("DIME_MASTER"."ACCOUNT_NUMBER")=4425050005218650
AND TO_NUMBER("DIME_MASTER"."CIN")=00335093464)
類型的列是NVARCHAR,但在查詢參數是數字。
Oracle必須將數字轉換爲字符串,但在投射時它有時不太聰明。
神諭和算命者並不總是對的;)
這些轉換可以防止查詢使用索引。
Select RELATIONSHIP
from DIME_MASTER
WHERE CIN=to_char(?) AND SSN=to_char(?) AND ACCOUNT_NUMBER=to_char(?)
然後運行這個命令::
使用顯式轉換成重寫查詢
exec dbms_stats.gather_table_stats(user, 'DIME_MASTER');
和運行查詢,並顯示了我們一個新的解釋計劃。
請您不要在這裏貼解釋計劃,他們是不可讀的,
請改用pastebin,並且只粘貼鏈接到這裏,謝謝。
看看這個簡單的例子,它說明了爲什麼你需要顯式轉換:
CREATE TABLE "DIME_MASTER" (
"ACCOUNT_NUMBER" NVARCHAR2(16)
);
insert into dime_master
select round(dbms_random.value(1, 100000)) from dual
connect by level <= 100000;
commit;
create index dime_master_acc_ix on dime_master(account_number);
explain plan for select * from dime_master
where account_number = 123;
select * from table(dbms_xplan.display);
Plan hash value: 1551952897
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 54 | 70 (3)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| DIME_MASTER | 3 | 54 | 70 (3)| 00:00:01 |
---------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(TO_NUMBER("ACCOUNT_NUMBER")=123)
explain plan for select * from dime_master
where account_number = to_char(123);
select * from table(dbms_xplan.display);
Plan hash value: 3367829596
---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 54 | 1 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| DIME_MASTER_ACC_IX | 3 | 54 | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("ACCOUNT_NUMBER"=U'123')
抱歉遲到的答覆,在看到您的答覆之前,我能夠發現它與oracle做to_char編號相同的東西,因此沒有使用必需的索引並花費更多的時間來執行查詢。我修改了我的查詢,如下所示: – user2639553
從DIME_MASTER中選擇RELATIONSHIP WHERE CIN =? AND SSN =? AND ACCOUNT_NUMBER =?和CIN如'?%'和SSN如'?%'和ACCOUNT_NUMBER LIKE'?%',它開始使用索引和查詢很快。 – user2639553
根據列的基數(總行數/唯一值) - 您可以在每列上創建位圖索引。對於and
/or
操作,位圖索引非常有用。
經驗法則表明,位圖索引對於基數超過10%是有用的。
create bitmap index DIME_MASTER_CIN_BIX on DIME_MASTER (CIN);
如何在查詢中使用它? – user2639553
我在DIME_MASTER(CIN)上爲CIN&SSN創建了2個位圖索引'創建位圖索引DIME_MASTER_CIN_BIX; 在DIME_MASTER(SSN)上創建位圖索引DIME_MASTER_SSN_BIX;'但性能沒有改進。查詢仍然需要11.3到11.5秒。 – user2639553
DIME_MASTER結構'CREATE TABLE 「DIME」。 「DIME_MASTER」 ( 「ACCOUNT_NUMBER」 NVARCHAR2(16), 「APPLICATION_NUMBER」 NVARCHAR2(14), 「FIRST_NAME」 NVARCHAR2(15), 「LAST_NAME」 NVARCHAR2(25 ), 「SSN」 NVARCHAR2(9), 「CIN」 NVARCHAR2(12), 「日期date_updated」 DATE, 「BOOK_INDICATOR」 NVARCHAR2(1), 「CARD_NUMBER」 NVARCHAR2(16), 「關係」 NVARCHAR2( 1) )' – user2639553
好放單指數'cin','ssn'和'account_number'的所有3個選擇性的順序(列中具有最獨特值的那個應該是第一個)。如果可能的話,使索引唯一...然後動態是可怕的...我假設你的意思是你改變變量而不是每次構建查詢。 – Ben
那麼,如果沒有適當的索引,難怪這是緩慢的......你嘗試了什麼?執行計劃顯示什麼? – ppeterka
**您需要向我們展示表格和索引定義**以及每個表格的行數。也許你的表格定義不好。也許索引沒有正確創建。也許你沒有一個你認爲你做過的那個專欄的索引。沒有看到表和索引定義,我們不能說。我們還需要行計數,因爲這會大大影響查詢優化。如果你知道如何做一個'EXPLAIN'或者得到一個執行計劃,那就把結果也放在問題中。 –