2013-05-16 106 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