2013-05-16 151 views
-1

我通過分析正採取多一點時間預期,我想調整它的一些下面的查詢。查詢的目的是從給定的device_id的Messages表中獲取最後3小時的數據,並通過上次消息接收(time desc)對結果進行排序。目前數據庫上有一個複合索引,看起來並不理想。任何索引或查詢語法都會更改建議以加快此查詢的速度?性能調優Oracle查詢

消息表結構:

色譜柱:

id (auto incremented PK NUMBER(10)) 
device_id 
model_id 
state 
creation_date (DATE when row was inserted) 
time (unix time message was transmitted) 
//a bunch of other columns omitted 

索引:

id 
device_id, model_id, state (composite index) 

查詢:

select * from messages where device_id='0-12345678' and creation_date > sysdate-3/24 order by time desc 
+0

什麼是查詢計劃?什麼是綜合指數?它是'device_id,creation_date'上的組合索引嗎?此查詢返回多少行?它運行得有多快?你需要多久才能運行? –

+1

'messages'表中有多少行? 'device_id'有多獨特?你根據沒有被索引的列選擇數據('device_id','creation_date'),難怪查詢很慢。 – npe

+0

消息表有6,354,837行。 Device_id可以具有多個關聯的消息,因此在該表中它不是唯一的。我沒有創建索引,這就是我問的原因。我相信索引應該改變 – c12

回答

3

您還沒有發佈解釋計劃,但它看起來像你會做全表掃描或索引範圍掃描下來DEVICE_ID,然後通過rowid單獨訪問每行,因爲您的整個選擇不在索引和DEVICE_ID不是唯一的。

沒有索引創建一個硬性的規則,但很一般,你應該指數,基數的順序(如何在列很多不同值),該值在WHERE子句。當你選擇一系列日期時,我建議在DEVICE_ID,CREATION_DATE上創建一個索引。

您還使用select *。如果你不需要選擇每一列,don't do this。這是多個字節的從磁盤讀取,有通過網絡發送等。如果你只選擇,DEVICE_IDCREATION_DATETIME我建議索引得到改變這些三列,在此爲了更多的字節,所以你根本不用觸摸表格,你可以從索引中選擇並排序。

如果業務邏輯指出,列這個名單應該是唯一的,然後創建唯一索引,而不是一個普通的一個。最後,如果你不要絕對需要ORDER BY然後刪除它。然後刪除需要額外時間的排序。

+0

我在原始問題的複合索引中存在拼寫錯誤,device_id是組合索引或組合索引。這會改變你的答案嗎? – c12

+0

不,如果你想加快速度@ C12 ......我州3個不同的東西,雖然,我會通過,如果你不需要它刪除訂單,降低選擇列數_before_爲你創建一個新索引維護索引,並佔用磁盤空間(如果這些事情中的任何一個很重要)。這一切都取決於它是多麼「緩慢」以及你想如何「快速」。 – Ben

+0

@Ben ...我需要訂單,我需要所有的列。 – c12