优化更新命令,该命令在每个行的整个表上聚合

时间:2013-02-05 22:39:11

标签: sql database sqlite sql-update

我有2个表,companyinvestment,我需要在公司表中有一个列,其中包含每家公司的投资数量。

顺便说一句,这是一个sqlite数据库。

我尝试了以下查询:

UPDATE company SET numlinks = (SELECT count(*) 
                                   FROM investment 
                                   WHERE investment.company_name = company.name);

我很确定查询是对的。如果我为一家公司运行它,行就会正确更新。但鉴于我有超过300K行,查询开始运行,似乎需要一段时间。

使用.timer ON命令为单个公司运行时,使用的CPU大约是0.03(我不确定单位,我猜它是几秒钟)

关于如何加快速度的任何想法?

2 个答案:

答案 0 :(得分:1)

您要做的是计算摘要,然后将它们加入到更新语句中。不幸的是,SQLite不支持连接(here),除非通过这种相关的子查询语法。

提高速度的一种方法是使用以下方法创建临时表:

select company_name, count(*) as cnt
from investment
group by company_name

然后用这张表做同样的事情:

set numlinks = (select cnt from TemporaryTable)

性能优势是双重的。首先,您不必为每一行重新计算。更重要的是,您可以在company_name上创建索引,从而显着加快查询速度。

答案 1 :(得分:1)

这是最简单的解决方案。

alter table company
drop column numlinks

数据库规范化的首要原则之一是不存储计算值。如果要显示链接数,请在需要时进行查询。

select company.name, other_stuff, count(*) links
from company join investment on company.name = investment.company_name
group by company.name, other_stuff

另外,根据您目前的设计,如果两家公司的名称相同,您就会遇到麻烦。这就是名称字段很少用于识别记录的原因。

如果无法理解这个答案,我听说过这本书的数据库设计的好消息。