2012-04-24 156 views
1

我有一个小问题;我有2个表格: eventsmultimediaevents具有删除sql查询非常慢

id, 
device_id 
created_at field 

主键是id并有由device_idcreated_at场形成的索引。

multimedia表具有随字段:

id 
device_id 
created_at 
data (this field is a blob field and contains a 20k string) 

主键是ID和有由device_idcreated_by场形成的索引。

问题是当我想在数据前删除与created_at的记录。

查询:

DELETE FROM events WHERE device_id = #{dev[0]} 
AND created_at <= '#{mm_critical_time.to_s}' 

是确定的。在5或6秒delete的记录。

查询

DELETE FROM multimedia WHERE device_id = #{dev[0]} 
AND created_at <= '#{mm_critical_time.to_s}' 

给我一些问题,执行开始,从来没有完成它。

有什么问题?

回答

2

您可能需要为正在搜索的列创建索引。

CREATE INDEX device_created_index 
ON multimedia (device_id, created_at); 

如果您想了解更多有关优化你的查询,请参阅我这里了有关使用EXPLAIN选择答案:is there better way to do these mysql queries?

+0

我已经创建索引 – Dabidi 2012-04-24 09:10:26

+0

那我建议你解释你的查询,在我挂答复中提到。 – 2012-04-24 11:27:09

0

的条件的顺序是非常重要的,你havent't告诉我们您的数据库服务器,但至少在甲骨文它,所以要尽量扭转他们像

DELETE FROM multimedia WHERE 
created_at <= '#{mm_critical_time.to_s}' 
AND device_id = #{dev[0]} 

或我们最快的部分内查询

DELETE FROM multimedia WHERE 
created_at <= '#{mm_critical_time.to_s}' 
AND device_id in (select device_id from multimedia where device_id = #{dev[0]}) 

此外,我总是打破缓慢的查询和速度测试部分,以便您知道瓶颈在哪里。 有些程序会显示查询花了多长时间,而在Ruby中您可以使用基准测试,您可以在测试时使用选择来补充删除。

这样的测试:

select * FROM multimedia WHERE created_at <= '#{mm_critical_time.to_s}' 

select * from multimedia WHERE device_id = #{dev[0]} 

成功..

0

这是很幼稚的,送给在关系数据库性能问题的解决方案,而无需知道整个故事,因为涉及很多变量。

对于你,尽管提供的数据,我建议你删除主键和索引,然后运行:

CREATE UNIQUE CLUSTERED INDEX uc ON events (device_id, created_at); 
CREATE UNIQUE CLUSTERED INDEX uc ON multimedia (device_id, created_at); 

如果你真的需要强制执行的id领域的独特性,创造一个独特的非聚集索引对每个表此列(但它会导致delete命令消耗更多时间):

CREATE UNIQUE INDEX ix_id ON events (id); 
CREATE UNIQUE INDEX ix_id ON multimedia (id);