1

我有一个小问题;我有 2 张桌子: eventsmultimedia. events

id, 
device_id
created_at field

主键是 id,并且有一个由device_idandcreated_at字段形成的索引。

multimedia表有以下字段:

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

主键是 id 并且有一个由device_idandcreated_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}'

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

有什么问题?

4

3 回答 3

2

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

CREATE INDEX device_created_index
ON multimedia (device_id, created_at);

如果您想了解有关优化查询的更多信息,请参阅我在此处给出的关于使用 EXPLAIN SELECT 的答案:是否有更好的方法来执行这些 mysql 查询?

于 2012-04-24T07:52:24.697 回答
0

在不了解整个故事的情况下为关系数据库中的性能问题提供解决方案是非常幼稚的,因为其中涉及许多变量。

但是,对于您提供的数据,我建议您删除主键和索引并运行:

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

如果确实需要强制执行id字段的唯一性,请在每个表上为该列创建一个唯一的非聚集索引(但这会导致删除命令消耗更多时间):

CREATE UNIQUE INDEX ix_id ON events (id);
CREATE UNIQUE INDEX ix_id ON multimedia (id);
于 2012-04-24T14:04:44.613 回答
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 * FROM multimedia WHERE created_at <= '#{mm_critical_time.to_s}' 

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

成功..

于 2012-04-24T11:11:03.713 回答