好的,所以我将一些数据从另一个连接中加载到表中(如果ts是时间戳列):
insert ignore into target_table select s.user_id,i.item_id,i.artist_id,s.ts
from source_table s join itemlist i on s.item_url = i.item_url;
问题是,我只想要在一定时间范围内来自内部的数据,所以我的问题是:用连接中的where子句来做这个会更快,即:
insert ignore into target_table select s.user_id,i.item_id,i.artist_id,s.ts
from source_table s join itemlist i on s.item_url = i.item_url where
ts< '2013-01-01' and ts >= '2005-07-01';
或者,要进行第一次查询,然后进行删除,即:
delete from target_table where ts>= '2013-01-01' and ts < '2005-07-01';
我知道我可以自己测试一下,但我也想了解为什么首选一种方法
答案 0 :(得分:1)
第一个版本应该更快:
insert ignore into target_table(user_id, item_id, artis_it, ts)
select s.user_id,i.item_id,i.artist_id,s.ts
from source_table s join
itemlist i
on s.item_url = i.item_url
where ts < '2013-01-01' and ts >= '2005-07-01';
以下是一些原因:
答案 1 :(得分:1)
(假设你的意思是第二个方法的WHERE子句实际上与第一个方法相反 - 否则你最终会得到不同的结果......)
它取决于表上的索引以及表中的数据量。
如果两个表都在ts
上有一个索引,那么我看不出它会产生差异很多,性能方面,假设行数不多,但它会更常见的是限制初始SELECT
,因此您只执行一次操作。
表格中的数据量是相关的。想想这个例子:source_table
中有十亿行,但只有一行符合您的条件。在这种情况下,带有SELECT
子句的索引WHERE
将非常快速地找到该行并将其复制到目标表中。但是,第二种方法会将十亿行复制到目标表,这将耗费很长时间(以及大量磁盘空间),然后您只需删除其中一行,这可能需要相当长的时间如果发现你要保留的行因索引而非常快。
插入然后删除也可能导致目标表中更多“碎片化”的数据,但这可能取决于存储引擎,我不太了解MySQL如何处理这样的事情来发表意见。
要记住的其他事项:如果您INSERT
然后DELETE
,则会有一段时间表中的数据“错误”。如果你没有包含在交易中并且INSERT
和DELETE
之间出现问题,那么它可能会出错。如果您只使用INSERT
执行WHERE
,那么这是一个atomic操作,可以完全成功或回滚。