我需要一些關於TimesTen DB查詢優化的幫助。我用Java分析器做了一些測量,發現大部分時間需要的代碼部分(這段代碼執行SQL查詢)。奇怪的是,這個查詢只對一些特定的輸入數據變得昂貴。SQL查詢性能優化(TimesTen)
下面是這個例子。我們有兩個查詢表,一個表示我們想要獲取的對象(T_PROFILEGROUP
),另一個表示來自其他表的多對多鏈接(T_PROFILECONTEXT_PROFILEGROUPS
)。我們不查詢鏈接表。
這些都是我用DB Profiler運行執行的查詢(它們是相同的除了ID):
Command> select G.M_ID from T_PROFILECONTEXT_PROFILEGROUPS CG, T_PROFILEGROUP G where CG.M_ID_EID = G.M_ID and CG.M_ID_OID = 1464837998949302272;
<1169655247309537280>
<1169655249792565248>
<1464837997699399681>
3 rows found.
Command> select G.M_ID from T_PROFILECONTEXT_PROFILEGROUPS CG, T_PROFILEGROUP G where CG.M_ID_EID = G.M_ID and CG.M_ID_OID = 1466585677823868928;
<1169655247309537280>
1 row found.
這是我在探查:
12:14:31.147 1 SQL 2L 6C 10825P Preparing: select G.M_ID from T_PROFILECONTEXT_PROFILEGROUPS CG, T_PROFILEGROUP G where CG.M_ID_EID = G.M_ID and CG.M_ID_OID = 1464837998949302272
12:14:31.147 2 SQL 4L 6C 10825P sbSqlCmdCompile()(E): (Found already compiled version: refCount:01, bucket:47) cmdType:100, cmdNum:1146695.
12:14:31.147 3 SQL 4L 6C 10825P Opening: select G.M_ID from T_PROFILECONTEXT_PROFILEGROUPS CG, T_PROFILEGROUP G where CG.M_ID_EID = G.M_ID and CG.M_ID_OID = 1464837998949302272;
12:14:31.147 4 SQL 4L 6C 10825P Fetching: select G.M_ID from T_PROFILECONTEXT_PROFILEGROUPS CG, T_PROFILEGROUP G where CG.M_ID_EID = G.M_ID and CG.M_ID_OID = 1464837998949302272;
12:14:31.148 5 SQL 4L 6C 10825P Fetching: select G.M_ID from T_PROFILECONTEXT_PROFILEGROUPS CG, T_PROFILEGROUP G where CG.M_ID_EID = G.M_ID and CG.M_ID_OID = 1464837998949302272;
12:14:31.148 6 SQL 4L 6C 10825P Fetching: select G.M_ID from T_PROFILECONTEXT_PROFILEGROUPS CG, T_PROFILEGROUP G where CG.M_ID_EID = G.M_ID and CG.M_ID_OID = 1464837998949302272;
12:14:31.228 7 SQL 4L 6C 10825P Fetching: select G.M_ID from T_PROFILECONTEXT_PROFILEGROUPS CG, T_PROFILEGROUP G where CG.M_ID_EID = G.M_ID and CG.M_ID_OID = 1464837998949302272;
12:14:31.228 8 SQL 4L 6C 10825P Closing: select G.M_ID from T_PROFILECONTEXT_PROFILEGROUPS CG, T_PROFILEGROUP G where CG.M_ID_EID = G.M_ID and CG.M_ID_OID = 1464837998949302272;
12:14:35.243 9 SQL 2L 6C 10825P Preparing: select G.M_ID from T_PROFILECONTEXT_PROFILEGROUPS CG, T_PROFILEGROUP G where CG.M_ID_EID = G.M_ID and CG.M_ID_OID = 1466585677823868928
12:14:35.243 10 SQL 4L 6C 10825P sbSqlCmdCompile()(E): (Found already compiled version: refCount:01, bucket:44) cmdType:100, cmdNum:1146697.
12:14:35.243 11 SQL 4L 6C 10825P Opening: select G.M_ID from T_PROFILECONTEXT_PROFILEGROUPS CG, T_PROFILEGROUP G where CG.M_ID_EID = G.M_ID and CG.M_ID_OID = 1466585677823868928;
12:14:35.243 12 SQL 4L 6C 10825P Fetching: select G.M_ID from T_PROFILECONTEXT_PROFILEGROUPS CG, T_PROFILEGROUP G where CG.M_ID_EID = G.M_ID and CG.M_ID_OID = 1466585677823868928;
12:14:35.243 13 SQL 4L 6C 10825P Fetching: select G.M_ID from T_PROFILECONTEXT_PROFILEGROUPS CG, T_PROFILEGROUP G where CG.M_ID_EID = G.M_ID and CG.M_ID_OID = 1466585677823868928;
12:14:35.243 14 SQL 4L 6C 10825P Closing: select G.M_ID from T_PROFILECONTEXT_PROFILEGROUPS CG, T_PROFILEGROUP G where CG.M_ID_EID = G.M_ID and CG.M_ID_OID = 1466585677823868928;
這是清楚地表明第一個查詢花費了近100ms,而第二個查詢則立即執行。這不是關於查詢預編譯(第一個也是預編譯的,因爲之前發生過相同的查詢)。我們在此使用的所有列都有DB索引:T_PROFILEGROUP.M_ID
,T_PROFILECONTEXT_PROFILEGROUPS.M_ID_OID
和T_PROFILECONTEXT_PROFILEGROUPS.M_ID_EID
。
我的問題是:
- 爲什麼查詢同一套表產生不同的參數,不同的表現?
- 這裏涉及哪些指標?
- 有什麼辦法可以改善這個簡單的查詢和/或數據庫,使其更快?
UPDATE:給大小的感覺:
Command> select count(*) from T_PROFILEGROUP;
<183840>
1 row found.
Command> select count(*) from T_PROFILECONTEXT_PROFILEGROUPS;
<2279104>
1 row found.
當然不是。我對執行此查詢的Java代碼進行了數千次的簡檔分析,而且顯然會導致性能瓶頸,只會導致通過此連接返回多行的ID。 – 2010-06-01 14:55:34