这是我无法理解的奇怪事情,我正在使用 PostGreSql9.2 ...
我有这个数据库:
movies (id, title, votes)
infos (id, movie_id, info_type, value)
我想用 infos.value 更新 movies.votes,加入 movies.id = infos.movie_if 并且只有 info_type = 100 (这是投票的类型..)
我尝试了 2 个不同的查询:
update movies
set votes = cast(i.value as integer)
from movies m inner join infos i on m.id = i.movie_id
where i.info_type = 100
其中(使用解释)预测运行时间约为 1100 万秒(太多了!)
第二次尝试:
update movies m
set votes = cast(
(
select value
from infos i
where i.info_type = 100 and i.movie_id = m.id
limit 1
) AS integer);
这应该是“只有”2万秒..还是太多了
我真的不知道查询计划是如何工作的,所以我尝试使用 ruby 脚本(使用 active_record)来做到这一点......这是:
Info.find_in_batches(:conditions => "info_type = 100") do |group|
group.each{ |info|
movie = Movie.find(info.movie_id)
movie.votes = info.value.to_i
movie.save
}
end
对于那些不读 ruby 的人来说,这个查询只是遍历所有满足 info_type = 100 条件的信息,然后为每个它搜索相应的电影并更新它。
而且速度非常快!只需几分钟,还有所有的 ruby/orm 开销!!
现在,为什么?知道电影大约有 60 万条记录,但只有 20 万条(三分之一)有带有票数的信息记录。这仍然不能解释正在发生的事情。