2013-02-28 48 views
0

我想优化下面的SQL,但我的SQL优化知识是相当绿色的,我没有取得多大进展(我概括了列和其他标识符由于公司策略)在当前状态下,此SQL根据负载运行1到2分钟之间的任何时间。 VKTINFO表包含约100万条记录,GNTINFO表包含约300万条记录。通常情况下,如果这是一个批处理过程,1-2分钟不会有什么大不了的,但是我们有代理需要这些信息,并尽可能快地生效 - 更糟糕的是,我们的系统最终超时并返回一个错误用户。但是,不能延长超时窗口。我们还有其他标准可以根据名字,邮政编码,帐户类型,帐户状态等等,但是当执行如下的广泛搜索时,查询变得相当慢。需要帮助优化非常慢的DB2 SQL查询触及数百万条记录

如果有任何关于如何操纵这个SQL来加速select的建议/技巧,我将不胜感激关于此事的任何想法。如果需要更多信息,我会很乐意尽可能提供符合我们公司政策的信息。

编辑: 这里要求的是VKTINFO和GNTINFO表的索引。

  • ACCOUNT_NUMBER
  • 到期日期
  • EFFECTIVE_DATE

指标为gnt_account_info和vkt_account_info:

  • pi_account_num
  • pi_policy_num_gid

指数为gntnad和vktnad表:

  • nad_account_number
  • nad_name_type

指数为gntpolrf和vktpolrf表:

  • xrf_account_number
select 
processing_system, 
total_premium, 
quote_by, 
email_address, 
account_number, 
expiration_date, 
account_state, 
xrf_file, 
customer_name 
from 
(
    select 
    'ABCD' as processing_system, 
    total_premium, 
    quote_by, 
    email_address, 
    account_number, 
    expiration_date, 
    account_state, 
    xrf_file, 
    customer_name 
    from vktinfo 
    left outer join vkt_account_info on account_number = pi_account_number 
    left outer join vktpolrf on account_number = xrf_account_number 
    left outer join VKTNAD on account_number = nad_account_number 
    and history_expiration_date=nad_history_expiration_date 
    and nad_name_type='HA' 
    WHERE effective_date >= '2013-02-01' 
    AND effective_date <= '2013-02-28' 
    AND customer_name like '_SMITH%' 
    AND account_state = 'South Carolina' 
    union all 
    select 
    'EFGH' as processing_system, 
    total_premium, 
    quote_by, 
    email_address, 
    account_number, 
    expiration_date, 
    account_state, 
    xrf_file, 
    customer_name 
    from gntinfo 
    left outer join gnt_account_info on account_number = pi_account_number 
    left outer join vktpolrf on account_number = xrf_account_number 
    left outer join GNTNAD on account_number = nad_account_number 
    and history_expiration_date=nad_history_expiration_date 
    and nad_name_type='HA' 
    WHERE effective_date >= '2013-02-01' 
    AND effective_date <= '2013-02-28' 
    AND customer_name like '_SMITH%' 
    AND account_state = 'South Carolina' 
) 
a 
order by customer_name ASC fetch first 1000 rows only WITH UR 
+3

请发布(添加到问题)你有什么索引。 – 2013-02-28 21:28:08

+0

这不会解决您的问题,但我建议在您的连接前加上 – 2013-02-28 21:32:53

+3

您可以将执行计划粘贴到您的问题中吗?联合SELECT语句中的WHERE子句是相同的;值得*测试*优化器是否会通过从子查询中切下两个WHERE子句并将其中一个子元素粘贴到外部查询中来做出更好的决策。但首先看执行计划。 – 2013-02-28 21:42:49

回答

1

我没有一个坚实的答案给你。但我确实有一些事情可以尝试。我了解您无权获得执行计划。

  • 检查与别人谁一直在那里了一会儿,询问您是否应该到能够运行EXPLAIN。
  • 您可能需要account_state上的索引。经验法则:索引连接条件或WHERE子句中使用的每一列。有时多列索引执行的效果要好于多个单列索引。
  • 尝试移动子查询的WHERE子句中的每个部分,即可以将移动到外部查询,并测试两件事。
    • 在外部查询中的普通WHERE子句中使用这些部分。
    • 重新排列外层查询,以便从 UNIONed子查询中选择,而不是对其进行内连接。
  • 确定是否有任何左外部联接可以被内部联接替换。存储“nad_name_type”的表是内连接的可能候选对象。 (你明白为什么吗?)
  • 测试子查询在作为视图实现时的性能。你可能需要DBA的帮助。 (如果他们不让你运行EXPLAIN,他们可能不会让你创建视图。)
  • 测试子查询在作为物化查询表实现时的性能。您也可能需要DBA帮助。
+0

Mike,谢谢你的建议。我今天上午根据你的要点深入探讨了这个问题,并注意到一个特点。我们有两列引用美国国家 - 您建议我们放置索引的account_state和代表客户家庭地址状态的另一列。家庭地址状态有一个索引,因为account_state没有(尽管在我们的SQL中使用)。作为一个概念证明,我换入索引状态列搜索反对代替非索引 - 160秒减少到1.5秒。我会考虑让DBA创建一个索引。 – 2013-03-01 16:50:38