首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有什么经验法则可以优化这样的sql查询吗?

有什么经验法则可以优化这样的sql查询吗?
EN

Database Administration用户
提问于 2013-09-09 11:24:57
回答 4查看 3.4K关注 0票数 2

这是我的第一个问题。虽然我已经从这个论坛上得到了上百次的帮助。我在优化sql查询方面遇到了困难。执行起来需要几个小时。记录集也足够大。这个问题不是我写的。所以,为了找到瓶颈,我试着删除条件子句,但这并没有什么区别。索引ID已经完成。

这里的任何一位sql专家都能给它一些启发吗?在下面的查询中是否还有任何微调空间?在DB2中承载数据库的服务器。我在sql方面不太专业。像往常一样谢谢。你好,诺

这是一个查询:

代码语言:javascript
复制
SELECT
HEALTH_INSURANCE.RISK_DETAIL_ID ,
POLICY_RISK_COVER.RISK_COVER_ID ,
HEALTH_INSURANCE.RD_POLICY_SYSTEM_NO ,
RD_POLICY_END_NO_IDX ,
HEALTH_INSURANCE.RD_POLICY_ID ,
HEALTH_INSURANCE.RD_LEVEL1_ID ,
HEALTH_INSURANCE.RD_SUM_INSURED_AMT_LC ,
HEALTH_INSURANCE.RD_PREMIUM_AMT_LC ,
POLICY_RISK_COVER.PREMIUM_AMOUNT_FC ,
POLICY_RISK_COVER.SUM_INSURED_AMT_FC ,
HEALTH_INSURANCE.RD_REC_TYPE ,
HEALTH_INSURANCE.RD_EFFECT_FROM_DT ,
HEALTH_INSURANCE.RD_EFFECT_TO_DT ,
HEALTH_INSURANCE.RD_END_EFFECT_FROM_DT ,
HEALTH_INSURANCE.SEX_MAS_CD ,
HEALTH_INSURANCE.MARITAL_STATUS_CD ,
HEALTH_INSURANCE.EMP_CATG ,
HEALTH_INSURANCE.NO_OF_DEPENDENTS ,
CAST((
CASE 
    WHEN HEALTH_INSURANCE.AUTHORITY_LETTER_NO IS NULL 
    THEN HEALTH_INSURANCE.EMP_AL_NO 
    ELSE HEALTH_INSURANCE.AUTHORITY_LETTER_NO 
END) AS INT) AS EMP_AL_NO ,
HEALTH_INSURANCE.DOB ,
HEALTH_INSURANCE.EFF_DATE ,
HEALTH_INSURANCE.EFF_DATE2 ,
HEALTH_INSURANCE.NAME ,
CAST((SUBSTR(HEALTH_INSURANCE.RELATIONSHIP_CD, 5,2)) AS INT) AS 
RELATIONSHIP_CD_S ,
HEALTH_INSURANCE.RELATIONSHIP_CD ,
HEALTH_INSURANCE.DESIGNATION ,
HEALTH_INSURANCE.BRANCH ,
HEALTH_INSURANCE.BANK_ACCOUNT ,
HEALTH_INSURANCE.BANK_BRANCH_NAME ,
HEALTH_INSURANCE.PRE_EXISTING_AILMENT ,
HEALTH_INSURANCE.AUTHORITY_LETTER_NO ,
HEALTH_INSURANCE.AGE ,
HEALTH_INSURANCE.REGION ,
HEALTH_INSURANCE.CNIC ,
HEALTH_INSURANCE.CO_CODE ,
HEALTH_INSURANCE.EMP_LOCATION ,
HEALTH_INSURANCE.SUB_LOCATION ,
CATEGORY_LIMIT_HEADER.CLH_SYSTEM_NO ,
CATEGORY_LIMIT_HEADER.CTH_SYS_ID ,
CATEGORY_LIMIT_HEADER.CTH_POL_SYS_ID ,
CATEGORY_LIMIT_HEADER.CTH_END_NO_IDX ,
CATEGORY_LIMIT_HEADER.CTH_END_SR_NO ,
CATEGORY_LIMIT_HEADER.CTH_CATEGORY ,
CATEGORY_LIMIT_DETAIL.CLD_SYS_ID ,
CATEGORY_LIMIT_DETAIL.CLDH_SYS_ID ,
CATEGORY_LIMIT_DETAIL.CLD_COVER_CD ,
CATEGORY_LIMIT_DETAIL.CLD_END_IDX ,
CATEGORY_LIMIT_DETAIL.CLD_COVER_DESC ,
CATEGORY_LIMIT_DETAIL.CLD_CLM_TYPE_LIMIT ,
CATEGORY_LIMIT_DETAIL.CLD_CLM_REL ,
CATEGORY_LIMIT_DETAIL.CLD_CLM_AGE_FROM ,
CATEGORY_LIMIT_DETAIL.CLD_CLM_AGE_TO ,
CATEGORY_LIMIT_DETAIL.CLD_CLM_RB_LIMIT ,
CATEGORY_LIMIT_DETAIL.CLD_CATEGORY_LIMIT_FC ,
CATEGORY_LIMIT_DETAIL.CLD_CATEGORY_PREM_FC 
FROM
DB2ADMIN.HEALTH_INSURANCE AS HEALTH_INSURANCE 
    INNER JOIN DB2ADMIN.POLICY_RISK_COVER AS POLICY_RISK_COVER 
    ON HEALTH_INSURANCE.RD_POLICY_SYSTEM_NO = POLICY_RISK_COVER.
    RC_POLICY_SYSTEM_NO AND
    TRIM(RD_LEVEL1_ID) = TRIM(RC_LEVEL1_ID) 
        INNER JOIN DB2ADMIN.CATEGORY_LIMIT_HEADER AS CATEGORY_LIMIT_HEADER 
        ON HEALTH_INSURANCE.RD_POLICY_ID = CATEGORY_LIMIT_HEADER.
        CTH_POL_SYS_ID AND
        HEALTH_INSURANCE.EMP_CATG = CATEGORY_LIMIT_HEADER.CTH_CATEGORY 
            INNER JOIN DB2ADMIN.CATEGORY_LIMIT_DETAIL AS 
            CATEGORY_LIMIT_DETAIL 
            ON CATEGORY_LIMIT_HEADER.CTH_SYS_ID = CATEGORY_LIMIT_DETAIL.
            CLDH_SYS_ID AND
            POLICY_RISK_COVER.RISK_COVER_CD = CATEGORY_LIMIT_DETAIL.
            CLD_COVER_CD AND
            HEALTH_INSURANCE.RELATIONSHIP_CD = CATEGORY_LIMIT_DETAIL.
            CLD_CLM_REL 
WHERE
COALESCE(HEALTH_INSURANCE.AGE, 1) BETWEEN CATEGORY_LIMIT_DETAIL.
CLD_CLM_AGE_FROM AND
CATEGORY_LIMIT_DETAIL.CLD_CLM_AGE_TO
EN

回答 4

Database Administration用户

发布于 2013-09-09 15:56:20

一些可能与你相关的经验法则。。。

  • 不要尝试在没有代表性解释计划的情况下调优查询。代表性的意思是从生产数据库或开发/测试数据库获得一个解释计划,该数据库具有几乎相同的行数和几乎相同的值分布,理想情况下运行在类似的硬件上。不同的行数和不同的值分布通常意味着不同的执行计划。
  • 确保统计数据是最新的。
  • 对JOIN子句中使用的每一列和WHERE子句中使用的每一列进行索引(或验证索引)。我认为每个dbms都使用索引实现主键约束和外键约束。过去有一些不允许你删除这样的索引,有一两个会让你。因为我处理的是许多不同的dbms,所以我不会费心记住哪个是哪个。当我需要知道的时候我就去查一下。那就查一查。
  • 一个多列索引可能比三个单列索引执行得更好。考虑一下合并指数。
  • 写出合适的地方条款。表达式COALESCE(HEALTH_INSURANCE.AGE, 1) BETWEEN one_column AND another_column必须计算每一行的COALESCE()函数--它不能使用索引。如果可能,将NULL替换为文字整数1,并使该列不可为空。(这并不总是实用的,但在子句常常是性能杀手的情况下是不可行的,特别是如果其他考虑因素引起了整个表格扫描。)
票数 5
EN

Database Administration用户

发布于 2013-09-09 23:37:09

确保您拥有支持查询的最佳索引。

1)如果在IBM或z/OS中使用DB2,则可以基于表达式创建索引。如果您正在为LUW使用DB2,那么您似乎没有这个特性(至少在10.1版中是这样):

如果不使用trim()无法正确地连接,那么考虑在RD_POLICY_SYSTEM_NO、RD_LEVEL1_ID、TRIM(RD_LEVEL1_ID)上创建索引,在RC_POLICY_SYSTEM_NO、RC_LEVEL1_ID、TRIM(RC_LEVEL1_ID)或这个概念的某些变体上创建另一个索引。

2)如果您在IBM中使用DB2:

如果某些联接列(如代码值)基数较低,则请考虑创建编码向量指标 埃维氏。例如,您可以在RD_LEVEL_ID上创建一个EVI。

票数 1
EN

Database Administration用户

发布于 2013-09-09 11:57:04

我会尝试将where子句中的中间部分更改为

代码语言:javascript
复制
COALESCE(HEALTH_INSURANCE.AGE, 1) >= CATEGORY_LIMIT_DETAIL.CLD_CLM_AGE_FROM 
AND COALESCE(HEALTH_INSURANCE.AGE, 1) < CATEGORY_LIMIT_DETAIL.CLD_CLM_AGE_TO+1

根据我的经验,这比大型唱片公司之间的速度要快。YMMV

票数 0
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/49565

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档