我們正在開發票務系統(“票證”是指我們捕獲問題或客戶聯系的 IT 票證,而不是允許參加某些活動的票證)。
這些票證可以參考一些其他(父)票證,這樣這些票證可以形成一棵樹。樹的深度(或高度?)通常相當低。也許 20% 的票有 1 個、2 個或最多 3 個祖先。
沒有祖先的票證(即“TICKET_VORGAENGER_ID” = null / “Vorgaenger”在德語中的意思是“祖先”)稱為根票證。我們有一個查詢,可以在根票證中搜索任何給定票證 ID。
SQL 如下所示:
SELECT CONNECT_BY_ROOT TICKET_ID AS TICKET_ID
FROM TICKET
WHERE TICKET_ID = :ticketId
START WITH TICKET_VORGAENGER_ID IS NULL
CONNECT BY PRIOR TICKET_ID = TICKET_VORGAENGER_ID;
:ticketId
是要搜索其根祖先的票證的 ID。
TICKET_ID (PK) 和 TICKET_VORGAENGER_ID 兩列都定義了索引。
出于某種奇怪的原因,這些查詢在我們的資料庫上平均需要 40 秒,最多可能需要 80(!)秒。目前我們在資料庫中有大約 350 萬張票,并且資料庫服務器非常強大。
為什么這些查詢需要這么長時間?它出什么問題了?它或多或少是從 Oracle 示例頁面中以 1:1 的比例拍攝的。
查詢的執行計劃如下所示:
Executionplan
---------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6390K| 158M| 22765 (62)| 00:00:01 |
|* 1 | FILTER | | | | | |
|* 2 | CONNECT BY NO FILTERING WITH START-WITH| | | | | |
| 3 | TABLE ACCESS FULL | TICKET | 3654K| 31M| 8877 (1)| 00:00:01 |
---------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("TICKET_ID"=TO_NUMBER(:1))
2 - access("TICKET_VORGAENGER_ID"=PRIOR "TICKET_ID")
filter("TICKET_VORGAENGER_ID" IS NULL)
讓我感到困惑的是:如果我們在此查詢中提到的所有列上都有索引,為什么這里會有“TABLE ACCESS FULL”?
任何想法或建議如何加快速度?
uj5u.com熱心網友回復:
如果 :ticketId 是根,那么 "START WITH TICKET_ID = :ticketId" 并且不需要 WHERE 子句,因為您正在尋找 NULL 并且 NULL 不在索引中,所以它不會單獨使用任何關于 ticket_id 的索引,這應該會觸發使用正確的索引。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/532685.html
標籤:甲骨文
上一篇:回傳最低分配員工