2014-11-05 76 views
0

我请求了一些建议。PostgreSQL CASE语句需要索引?

我写了一个CASE语句来填充一个新字段。对于超过3亿条记录的数据库表,大约需要12个小时。

UPDATE line 
    SET code = (CASE 
     WHEN (group ='{Building}' and term = '{Outline}') then 1 
     WHEN (group ='{Building}' and term = '{Division}') then 2 
     WHEN (group ='{Building}' and term = '{Partial}') then 3 
    ELSE 99   
    END) 
    WHERE code is null; 

我该怎么做才能提高这种性能?

在运行case语句之前,我应该在代码列中添加一个索引,以便它能够更快地查找具有NULL代码值的记录。

或者我应该在列“组”和“期限”上创建索引以加快速度。

有了这么大的表格,创建任何索引需要一段时间,因此它必须平衡创建它们所需的时间和最终的性能增益。

感谢您的任何意见

编辑 其他信息在Windows 2008 Server上使用PostgreSQL 9.2 64位

上午 我已经使用了PostgreSQL的调整wiki和优化了postgresql.conf文件 我已经做了VACUUME和ANALYZE在桌子上

+1

http://wiki.postgresql.org/wiki/SlowQueryQuestions但'code'上的索引将有所帮助。如果代码为空的行数相对较少,那么甚至可能使用部分索引,条件为'where code is null' – 2014-11-05 11:06:42

+0

可以使用单独的请求: UPDATE行SET代码= 1其中group ='{Building}'和term ='{Outline}'且代码为空; UPDATE行SET代码= 2其中group ='{Building}'和term ='{Division}'且代码为空; UPDATE行SET代码= 3其中group ='{Building}'和term ='{Partial}'且代码为空; UPDATE行SET代码= 99其中代码为空; 你能为每个请求提供EXPLAIN结果吗? – 2014-11-05 11:30:12

+0

@VitaliyPro“线上更新(成本= 0.00..48847898.66行= 41740宽度= 996)” “ - > Seq在线扫描(成本= 0.00..48847898.66行= 41740宽度= 996)” “过滤器:((code IS NULL)AND(group ='{Building}':: characters varying [])AND(term ='{Outline}':: characters varying [])))“ – tjmgis 2014-11-05 13:59:31

回答

3

code上的索引不会帮助case声明,但它会帮助where。实际上有一个“付诸实施”,因为索引需要更新以及原始数据。所以,如果所有的code值在NULL之内,索引就不会更快。

groupterm的指标将有助于如果你分成单独的更新这样的:

UPDATE line 
    SET code = 1 
    WHERE code is null and group = '{Building}' and term = '{Outline}'; 

其实,你想索引line(code, group, term)这些。

0

,如果你有大量的行,请尝试:

编辑postgresql.conf中和 增加CHECKPOINT_SEGMENTS 10以上 增加wal_buffers到(> =你的表的300Mio记录的空间) 16MB(或更高版本)

你也可以得到更多的表现,如果你切换
FSYNC关闭 但是,你有一个风险数据丢失!

代码索引将加速更新(请参阅doku): “另外,索引列上的IS NULL或IS NOT NULL情况可以与B树索引一起使用。