2014-02-12 61 views
-1

请帮我检查sql,有什么问题吗?可以优化吗?执行需要很长时间,但并非总是如此。DB2 SQL优化建议

SELECT count(*) 
FROM DB2INST3.VWQueue1_119 
WHERE inbasketName is not null 
AND userid1 is not null 
AND nItemIndex is not null 
AND string1 is not null 
AND (F_BoundUser = ? OR F_BoundUser = ?) 
AND (F_Locked < 2) 
AND ((inbasketName='PSIQUEUE1Index') AND (inbasketName='PSIQUEUE1Index')) 

得到快照为:汇编

执行次数= 12942数 = 1最坏的准备时间(ms)= 6最好准备时间(ms)= 6个删除内部行= 0内部 行插入= 0的行读取= 1399262666执行时间总计(sec.microsec)= 3600.704315总 用户CPU时间(sec.microsec)= 2538.101110总系统CPU时间 (sec.microsec)= 0.191321

+0

爱那个模式/表命名约定 –

+0

这个语句看起来很简单,没有太多的优化可以完成(F_Bounduser在那里两次?)。从你的表名判断,你正在从视图中选择......可能你的性能问题在那里。 @MitchWheat - 图中有一个VWQueue1_001到VWQueue1_99999? – Twelfth

+0

这是一个物理表。 – Sun

回答

0

这是您的查询的简化:

SELECT count(*) 
FROM DB2INST3.VWQueue1_119 
WHERE userid1 is not null and 
     nItemIndex is not null and 
     string1 is not null and 
     (F_BoundUser in (?, ?) and 
     (F_Locked < 2) and 
     (inbasketName = 'PSIQUEUE1Index') 

下面是变化:

  • 条件inbasketName='PSIQUEUE1Index'被提及两次。 Npt必要。
  • 条件inbasketName is not null是多余的,因为该值正在与字符串进行比较。

唯一最有帮助的指标是:VWQueue1_119(inbasketName, F_BoundUser, F_Locked)。如果表格中有大量其他列,则添加userid1,nItemIndexstring1将创建覆盖索引,以便不触摸原始数据页面。

0

在索引列上使用OR的条件会导致索引不被使用。幸运的是有一个简单的修复。

更改此:

AND (F_BoundUser = ? OR F_BoundUser = ?) 

要这样:

AND F_BoundUser IN (?, ?) 

虽然两种实现完全是一回事,优化器将(倾向于)使用索引与IN(),但不为OR。

此外,无论如何它更优雅。

这是我成功使用过很多次的东西。

+0

需要多少开销?有时需要〜200ms才能执行,这有意义吗? – Sun

+0

不,这没有意义。其中一个或两个值为null?表可以被另一个进程锁定吗? – Bohemian

+0

我检查了锁,没有问题。 – Sun

0

你可以指望0:

SELECT COUNT(0) 
... 

如果optimizator是不是在一个较高的水平,DB2将预取列只是指望他们。使用0时,DB2将使用其他方式,如仅索引或统计信息。