删除sql查询非常慢

时间:2012-04-24 07:42:34

标签: sql ruby sql-delete

我有点问题; 我有2张桌子: eventsmultimedia。 <{1}}有

events

主键是id,并且有一个由id, device_id created_at field device_id字段组成的索引。

created_at表有关注者字段:

multimedia

主键是id,并且有一个由id device_id created_at data (this field is a blob field and contains a 20k string) device_id字段组成的索引。

问题在于我想在数据之前删除created_by的记录。

查询:

created_at

没问题。在5或6秒DELETE FROM events WHERE device_id = #{dev[0]} AND created_at <= '#{mm_critical_time.to_s}' 记录。

查询

delete

给我一​​些问题,执行开始,永远不会完成。

有什么问题?

3 个答案:

答案 0 :(得分:2)

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

CREATE INDEX device_created_index
ON multimedia (device_id, created_at);

如果您想了解有关优化查询的更多信息,请参阅我在此处使用EXPLAIN SELECT给出的答案:is there better way to do these mysql queries?

答案 1 :(得分:0)

条件的顺序很重要,你没有告诉我们你的数据库服务器,但至少在Oracle中它是,所以试着反转它们像

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补充删除。

所以测试:

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

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

成功..

答案 2 :(得分: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);