首页 文章 精选 留言 我的

精选列表

搜索[日活数],共10000篇文章
优秀的个人博客,低调大师

数仓实践丨常量标量子查询做全连接导致整体慢

本文分享自华为云社区《GaussDB(DWS)性能调优:常量标量子查询做全连接导致整体慢》,作者: Zawami 。 问题描述 由于SQL中存在标量子查询同另一查询做笛卡尔积使SQL整体慢。标量子查询,即结果集只有一行一列的子查询。这里导致的SQL语句执行慢不只是在于做笛卡尔积慢,也会使后续聚合更慢。 原始语句 WITH TMP AS( SELECT case when length('[“202309“]') = 6 then '[“202309“]' || '01' WHEN length('[“202309“]') <> 8 THEN TO_CHAR(CURRENT_DATE, 'YYYYMMDD') END AS V_DATE from DUAL ) SELECT BG_CODE, BG_CN_NAME, BG_EN_NAME, METRIC_CODE --指标ID , METRIC_CN_NAME --指标中文名称 , METRIC_EN_NAME --指标英文名称 , CURRENCY --币种 , OVERSEAS_FLAG, REGION_CODE, REGION_CN_NAME, REGION_EN_NAME, REPOFFICE_CODE, REPOFFICE_CN_NAME, REPOFFICE_EN_NAME, OFFICE_CODE, OFFICE_CN_NAME, OFFICE_EN_NAME, REGION_CUSTCATG_CODE, REGION_CUSTCATG_CN_NAME, REGION_CUSTCATG_EN_NAME, TOP_CUST_CATEGORY_CODE, TOP_CUST_CATEGORY_EN_NAME, TOP_CUST_CATEGORY_CN_NAME, ACCTCUST_HQ_CODE, ACCTCUST_HQ_CN_NAME, ACCTCUST_HQ_EN_NAME, ACCTCUST_BRANCH_CODE, ACCTCUST_BRANCH_CN_NAME, ACCTCUST_BRANCH_EN_NAME, ACCTCUST_SUBSIDIARY_CODE, ACCTCUST_SUBSIDIARY_CN_NAM, ACCTCUST_SUBSIDIARY_EN_NAM, COUNTRY_CODE --新增加入参 , COUNTRY_CN_NAME --新增加入参 , COUNTRY_EN_NAME --新增加入参 , AGREE_AMOUNT --BUSI_DSCT_00001 总优惠 , AGREE_REMAIN_AMOUNT --BUSI_DSCT_00002 即期优惠 , SIGN_AMOUNT --BUSI_DSCT_00003 即期优惠/一次性优惠 , USE_AMOUNT --BUSI_DSCT_00004 即期优惠/单价量折扣 , NOT_USED_VALID_AMOUNT --BUSI_DSCT_00005 延期优惠 , NOT_USED_INVALID_AMOUNT --BUSI_DSCT_00006 voucher , NEW_SIGN_AMOUNT --BUSI_DSCT_00007 其他延期优惠 , NEW_USE_AMOUNT --BUSI_DSCT_00008 本月新使用金额 , EXPIRED_AMOUNT --BUSI_DSCT_00009 本月已过期金额 , IMMED_EXPIRED_AMOUNT --BUSI_DSCT_00010 半年内即将过期金额 FROM ( SELECT C.BG_CODE, C.BG_CN_NAME, C.BG_EN_NAME, C.M_ID AS METRIC_CODE --指标ID , C.M_CN AS METRIC_CN_NAME --指标中文名称 , C.M_EN AS METRIC_EN_NAME --指标英文名称 , C.CURRENCY_CODE AS CURRENCY --币种 ,CASE WHEN 1 = 0 THEN C.OVERSEA_FLAG ELSE NULL END AS OVERSEAS_FLAG,CASE WHEN 1 = 0 THEN C.REGION_CODE ELSE NULL END AS REGION_CODE,CASE WHEN 1 = 0 THEN C.REGION_CN_NAME ELSE NULL END AS REGION_CN_NAME,CASE WHEN 1 = 0 THEN C.REGION_EN_NAME ELSE NULL END AS REGION_EN_NAME,CASE WHEN 1 = 0 THEN C.REPOFFICE_CODE ELSE NULL END AS REPOFFICE_CODE,CASE WHEN 1 = 0 THEN C.REPOFFICE_CN_NAME ELSE NULL END AS REPOFFICE_CN_NAME,CASE WHEN 1 = 0 THEN C.REPOFFICE_EN_NAME ELSE NULL END AS REPOFFICE_EN_NAME,CASE WHEN 1 = 0 THEN C.OFFICE_CODE ELSE NULL END AS OFFICE_CODE,CASE WHEN 1 = 0 THEN C.OFFICE_CN_NAME ELSE NULL END AS OFFICE_CN_NAME,CASE WHEN 1 = 0 THEN C.OFFICE_EN_NAME ELSE NULL END AS OFFICE_EN_NAME,CASE WHEN 1 = 0 THEN C.REGION_CUSTCATG_CODE ELSE NULL END AS REGION_CUSTCATG_CODE,CASE WHEN 1 = 0 THEN C.REGION_CUSTCATG_CN_NAME ELSE NULL END AS REGION_CUSTCATG_CN_NAME,CASE WHEN 1 = 0 THEN C.REGION_CUSTCATG_EN_NAME ELSE NULL END AS REGION_CUSTCATG_EN_NAME,CASE WHEN 1 = 0 THEN C.TOP_CUST_CATEGORY_CODE ELSE NULL END AS TOP_CUST_CATEGORY_CODE,CASE WHEN 1 = 0 THEN C.TOP_CUST_CATEGORY_EN_NAME ELSE NULL END AS TOP_CUST_CATEGORY_EN_NAME,CASE WHEN 1 = 0 THEN C.TOP_CUST_CATEGORY_CN_NAME ELSE NULL END AS TOP_CUST_CATEGORY_CN_NAME,CASE WHEN 1 = 0 THEN C.ACCTCUST_HQ_CODE ELSE NULL END AS ACCTCUST_HQ_CODE,CASE WHEN 1 = 0 THEN C.ACCTCUST_HQ_CN_NAME ELSE NULL END AS ACCTCUST_HQ_CN_NAME,CASE WHEN 1 = 0 THEN C.ACCTCUST_HQ_EN_NAME ELSE NULL END AS ACCTCUST_HQ_EN_NAME,CASE WHEN 1 = 0 THEN C.ACCTCUST_BRANCH_CODE ELSE NULL END AS ACCTCUST_BRANCH_CODE,CASE WHEN 1 = 0 THEN C.ACCTCUST_BRANCH_CN_NAME ELSE NULL END AS ACCTCUST_BRANCH_CN_NAME,CASE WHEN 1 = 0 THEN C.ACCTCUST_BRANCH_EN_NAME ELSE NULL END AS ACCTCUST_BRANCH_EN_NAME,CASE WHEN 1 = 0 THEN C.ACCTCUST_SUBSIDIARY_CODE ELSE NULL END AS ACCTCUST_SUBSIDIARY_CODE,CASE WHEN 1 = 0 THEN C.ACCTCUST_SUBSIDIARY_CN_NAM ELSE NULL END AS ACCTCUST_SUBSIDIARY_CN_NAM,CASE WHEN 1 = 0 THEN C.ACCTCUST_SUBSIDIARY_EN_NAM ELSE NULL END AS ACCTCUST_SUBSIDIARY_EN_NAM,CASE WHEN 1 = 0 THEN C.COUNTRY_CODE ELSE NULL END AS COUNTRY_CODE --新增加入参 ,CASE WHEN 1 = 0 THEN C.COUNTRY_CN_NAME ELSE NULL END AS COUNTRY_CN_NAME --新增加入参 ,CASE WHEN 1 = 0 THEN C.COUNTRY_EN_NAME ELSE NULL END AS COUNTRY_EN_NAME --新增加入参 , SUM(C.AGREE_AMOUNT) AS AGREE_AMOUNT --协议金额 , SUM(C.AGREE_REMAIN_AMOUNT) AS AGREE_REMAIN_AMOUNT --协议剩余金额 , SUM(C.SIGN_AMOUNT) AS SIGN_AMOUNT --可用金额 , SUM(C.USE_AMOUNT) AS USE_AMOUNT --已使用金额 , SUM( CASE WHEN C.DSCT_TYPE = 'VOUCHER' AND NVL( C.EXPIRED_DATE, add_months(C.EFFECTIVE_DATE, C.VALID_MONTH) ) >= to_date(T.V_DATE, 'yyyymmdd') THEN C.AGREE_REMAIN_AMOUNT WHEN C.DSCT_TYPE in ( 'FOC', 'Volume Based List Price Adjustment', 'One-Time Discount' ) AND C.DSCT_END_DATE >= to_date(T.V_DATE, 'yyyymmdd') THEN C.EFFECTIVE_TOTAL_AMOUNT ELSE NULL END ) AS NOT_USED_VALID_AMOUNT --未使用金额(有效期外) , SUM( CASE WHEN C.DSCT_TYPE = 'VOUCHER' THEN C.SIGN_AMOUNT ELSE C.EFFECTIVE_TOTAL_AMOUNT END - CASE WHEN C.DSCT_TYPE = 'VOUCHER' THEN C.USE_AMOUNT ELSE C.USED_TOTAL_AMOUNT END - CASE WHEN C.DSCT_TYPE = 'VOUCHER' AND NVL( C.EXPIRED_DATE, add_months(C.EFFECTIVE_DATE, C.VALID_MONTH) ) >= to_date(T.V_DATE, 'yyyymmdd') THEN C.AGREE_REMAIN_AMOUNT WHEN C.DSCT_TYPE in ( 'FOC', 'Volume Based List Price Adjustment', 'One-Time Discount' ) AND C.DSCT_END_DATE >= to_date(T.V_DATE, 'yyyymmdd') THEN C.EFFECTIVE_TOTAL_AMOUNT ELSE NULL END ) AS NOT_USED_INVALID_AMOUNT --未使用金额(有效期内) , SUM( CASE WHEN C.DSCT_TYPE = 'VOUCHER' AND C.EXPIRED_DATE >= to_date(substr(T.V_DATE, 1, 6), 'yyyymm') and C.EXPIRED_DATE <= LAST_DAY(to_date(T.V_DATE, 'yyyymmdd')) THEN C.SIGN_AMOUNT WHEN C.DSCT_TYPE in ( 'FOC', 'Volume Based List Price Adjustment', 'One-Time Discount' ) AND C.DSCT_START_DATE >= to_date(substr(T.V_DATE, 1, 6), 'yyyymm') and C.DSCT_START_DATE <= LAST_DAY(to_date(T.V_DATE, 'yyyymmdd')) THEN C.EFFECTIVE_TOTAL_AMOUNT ELSE NULL END ) AS NEW_SIGN_AMOUNT --本月新增可用金额 , SUM( CASE WHEN C.DSCT_TYPE = 'VOUCHER' AND C.EFFECTIVE_DATE >= to_date(substr(T.V_DATE, 1, 6), 'yyyymm') and C.EFFECTIVE_DATE <= LAST_DAY(to_date(T.V_DATE, 'yyyymmdd')) THEN C.USE_AMOUNT WHEN C.DSCT_TYPE in ( 'FOC', 'Volume Based List Price Adjustment', 'One-Time Discount' ) AND C.DSCT_START_DATE >= to_date(substr(T.V_DATE, 1, 6), 'yyyymm') and C.DSCT_START_DATE <= LAST_DAY(to_date(T.V_DATE, 'yyyymmdd')) THEN C.USED_TOTAL_AMOUNT ELSE NULL END ) AS NEW_USE_AMOUNT --本月新使用金额 , SUM( CASE WHEN C.DSCT_TYPE = 'VOUCHER' AND C.EXPIRED_DATE < to_date(T.V_DATE, 'yyyymmdd') THEN C.AGREE_REMAIN_AMOUNT WHEN C.DSCT_TYPE in ( 'FOC', 'Volume Based List Price Adjustment', 'One-Time Discount' ) AND C.DSCT_END_DATE < to_date(T.V_DATE, 'yyyymmdd') THEN C.EFFECTIVE_TOTAL_AMOUNT ELSE NULL END ) AS EXPIRED_AMOUNT --本月已过期金额 , SUM( CASE WHEN C.DSCT_TYPE = 'VOUCHER' AND C.EXPIRED_DATE BETWEEN to_date(T.V_DATE, 'yyyymmdd') AND add_months(to_date(T.V_DATE, 'yyyymmdd'), 6) THEN C.AGREE_REMAIN_AMOUNT WHEN C.DSCT_TYPE in ( 'FOC', 'Volume Based List Price Adjustment', 'One-Time Discount' ) AND C.DSCT_END_DATE BETWEEN to_date(T.V_DATE, 'yyyymmdd') AND add_months(to_date(T.V_DATE, 'yyyymmdd'), 6) THEN C.EFFECTIVE_TOTAL_AMOUNT ELSE NULL END ) AS IMMED_EXPIRED_AMOUNT --半年内即将过期金额 FROM DMSALESW.DM_SALE_BUSI_DSCT_SUM_F C LEFT JOIN TMP T ON 1 = 1 WHERE C.CURRENCY_CODE IN ('USD') --改为多值 AND C.BG_CODE IN ('PDCG901159') AND C.M_ID IN ( 'BUSI_DSCT_00001', 'BUSI_DSCT_00002', 'BUSI_DSCT_00003', 'BUSI_DSCT_00004', 'BUSI_DSCT_00005', 'BUSI_DSCT_00006', 'BUSI_DSCT_00007' ) --新增加字段 --AND C.M_CN IN ('#[#P_REPORT_ITEM_NAME#]#') --新增加字段 --新增加字段 GROUP BY C.BG_CODE, C.BG_CN_NAME, C.BG_EN_NAME, C.M_ID --指标ID , C.M_CN --指标中文名称 , C.M_EN --指标英文名称 , C.CURRENCY_CODE --币种 ,CASE WHEN 1 = 0 THEN C.OVERSEA_FLAG ELSE NULL END,CASE WHEN 1 = 0 THEN C.REGION_CODE ELSE NULL END,CASE WHEN 1 = 0 THEN C.REGION_CN_NAME ELSE NULL END,CASE WHEN 1 = 0 THEN C.REGION_EN_NAME ELSE NULL END,CASE WHEN 1 = 0 THEN C.REPOFFICE_CODE ELSE NULL END,CASE WHEN 1 = 0 THEN C.REPOFFICE_CN_NAME ELSE NULL END,CASE WHEN 1 = 0 THEN C.REPOFFICE_EN_NAME ELSE NULL END,CASE WHEN 1 = 0 THEN C.OFFICE_CODE ELSE NULL END,CASE WHEN 1 = 0 THEN C.OFFICE_CN_NAME ELSE NULL END,CASE WHEN 1 = 0 THEN C.OFFICE_EN_NAME ELSE NULL END,CASE WHEN 1 = 0 THEN C.REGION_CUSTCATG_CODE ELSE NULL END,CASE WHEN 1 = 0 THEN C.REGION_CUSTCATG_CN_NAME ELSE NULL END,CASE WHEN 1 = 0 THEN C.REGION_CUSTCATG_EN_NAME ELSE NULL END,CASE WHEN 1 = 0 THEN C.TOP_CUST_CATEGORY_CODE ELSE NULL END,CASE WHEN 1 = 0 THEN C.TOP_CUST_CATEGORY_EN_NAME ELSE NULL END,CASE WHEN 1 = 0 THEN C.TOP_CUST_CATEGORY_CN_NAME ELSE NULL END,CASE WHEN 1 = 0 THEN C.ACCTCUST_HQ_CODE ELSE NULL END,CASE WHEN 1 = 0 THEN C.ACCTCUST_HQ_CN_NAME ELSE NULL END,CASE WHEN 1 = 0 THEN C.ACCTCUST_HQ_EN_NAME ELSE NULL END,CASE WHEN 1 = 0 THEN C.ACCTCUST_BRANCH_CODE ELSE NULL END,CASE WHEN 1 = 0 THEN C.ACCTCUST_BRANCH_CN_NAME ELSE NULL END,CASE WHEN 1 = 0 THEN C.ACCTCUST_BRANCH_EN_NAME ELSE NULL END,CASE WHEN 1 = 0 THEN C.ACCTCUST_SUBSIDIARY_CODE ELSE NULL END,CASE WHEN 1 = 0 THEN C.ACCTCUST_SUBSIDIARY_CN_NAM ELSE NULL END,CASE WHEN 1 = 0 THEN C.ACCTCUST_SUBSIDIARY_EN_NAM ELSE NULL END,CASE WHEN 1 = 0 THEN C.COUNTRY_CODE ELSE NULL END --新增加入参 ,CASE WHEN 1 = 0 THEN C.COUNTRY_CN_NAME ELSE NULL END --新增加入参 ,CASE WHEN 1 = 0 THEN C.COUNTRY_EN_NAME ELSE NULL END ) T --新增加入参 从SQL中可以看到TMP为标量子查询,并且在子查询T中和物理表C做了笛卡尔积。 下面是该SQL的执行计划: id | operation | A-time | A-rows | E-rows | E-distinct | Peak Memory | E-memory | A-width | E-width | E-costs ----+-------------------------------------------------------------------------+----------------------+---------+---------+------------+----------------+----------+-----------+---------+----------- 1 | -> Row Adapter | 3037.648 | 7 | 245 | | 419KB | | | 1318 | 117210.62 2 | -> Vector Streaming (type: GATHER) | 3037.633 | 7 | 245 | | 777KB | | | 1318 | 117210.62 3 | -> Vector Hash Aggregate | [3031.872, 3032.516] | 7 | 245 | | [4MB, 4MB] | 16MB | [0,870] | 557 | 117128.41 4 | -> Vector Streaming(type: REDISTRIBUTE) | [3031.560, 3032.232] | 112 | 3920 | | [1MB, 1MB] | 2MB | | 557 | 116852.33 5 | -> Vector Hash Aggregate | [2728.059, 2909.255] | 112 | 3920 | | [8MB, 8MB] | 16MB | [833,833] | 557 | 116699.48 6 | -> Vector Nest Loop Left Join (7, 8) | [441.050, 471.725] | 3007901 | 2106919 | | [1MB, 1MB] | 1MB | | 237 | 67316.28 7 | -> CStore Scan on dmsalesw.dm_sale_busi_dsct_sum_f c | [145.354, 158.560] | 3007901 | 2106919 | | [5MB, 5MB] | 1MB | | 205 | 65011.82 8 | -> Vector Materialize | [32.034, 38.902] | 3007901 | 1 | | [288KB, 288KB] | 16MB | [21,21] | 32 | 0.03 9 | -> Vector Subquery Scan on dual | [0.067, 0.093] | 16 | 1 | | [128KB, 128KB] | 1MB | | 32 | 0.02 10 | -> Vector Adapter | [0.005, 0.006] | 16 | 1 | | [40KB, 40KB] | 1MB | | 0 | 0.01 11 | -> Result | [0.001, 0.002] | 16 | 1 | | [8KB, 8KB] | 1MB | | 0 | 0.01 把TMP作为一列放到T中后,性能有明显提升。 EXPLAIN PERFORMANCE SELECT BG_CODE, BG_CN_NAME, BG_EN_NAME, METRIC_CODE --指标ID , METRIC_CN_NAME --指标中文名称 , METRIC_EN_NAME --指标英文名称 , CURRENCY --币种 , OVERSEAS_FLAG, REGION_CODE, REGION_CN_NAME, REGION_EN_NAME, REPOFFICE_CODE, REPOFFICE_CN_NAME, REPOFFICE_EN_NAME, OFFICE_CODE, OFFICE_CN_NAME, OFFICE_EN_NAME, REGION_CUSTCATG_CODE, REGION_CUSTCATG_CN_NAME, REGION_CUSTCATG_EN_NAME, TOP_CUST_CATEGORY_CODE, TOP_CUST_CATEGORY_EN_NAME, TOP_CUST_CATEGORY_CN_NAME, ACCTCUST_HQ_CODE, ACCTCUST_HQ_CN_NAME, ACCTCUST_HQ_EN_NAME, ACCTCUST_BRANCH_CODE, ACCTCUST_BRANCH_CN_NAME, ACCTCUST_BRANCH_EN_NAME, ACCTCUST_SUBSIDIARY_CODE, ACCTCUST_SUBSIDIARY_CN_NAM, ACCTCUST_SUBSIDIARY_EN_NAM, COUNTRY_CODE --新增加入参 , COUNTRY_CN_NAME --新增加入参 , COUNTRY_EN_NAME --新增加入参 , AGREE_AMOUNT --BUSI_DSCT_00001 总优惠 , AGREE_REMAIN_AMOUNT --BUSI_DSCT_00002 即期优惠 , SIGN_AMOUNT --BUSI_DSCT_00003 即期优惠/一次性优惠 , USE_AMOUNT --BUSI_DSCT_00004 即期优惠/单价量折扣 , NOT_USED_VALID_AMOUNT --BUSI_DSCT_00005 延期优惠 , NOT_USED_INVALID_AMOUNT --BUSI_DSCT_00006 voucher , NEW_SIGN_AMOUNT --BUSI_DSCT_00007 其他延期优惠 , NEW_USE_AMOUNT --BUSI_DSCT_00008 本月新使用金额 , EXPIRED_AMOUNT --BUSI_DSCT_00009 本月已过期金额 , IMMED_EXPIRED_AMOUNT --BUSI_DSCT_00010 半年内即将过期金额 FROM ( SELECT case when length('[“202309“]') = 6 then '[“202309“]' || '01' WHEN length('[“202309“]') <> 8 THEN TO_CHAR(CURRENT_DATE, 'YYYYMMDD') END AS V_DATE, C.BG_CODE, C.BG_CN_NAME, C.BG_EN_NAME, C.M_ID AS METRIC_CODE --指标ID , C.M_CN AS METRIC_CN_NAME --指标中文名称 , C.M_EN AS METRIC_EN_NAME --指标英文名称 , C.CURRENCY_CODE AS CURRENCY --币种 ,CASE WHEN 1 = 0 THEN C.OVERSEA_FLAG ELSE NULL END AS OVERSEAS_FLAG,CASE WHEN 1 = 0 THEN C.REGION_CODE ELSE NULL END AS REGION_CODE,CASE WHEN 1 = 0 THEN C.REGION_CN_NAME ELSE NULL END AS REGION_CN_NAME,CASE WHEN 1 = 0 THEN C.REGION_EN_NAME ELSE NULL END AS REGION_EN_NAME,CASE WHEN 1 = 0 THEN C.REPOFFICE_CODE ELSE NULL END AS REPOFFICE_CODE,CASE WHEN 1 = 0 THEN C.REPOFFICE_CN_NAME ELSE NULL END AS REPOFFICE_CN_NAME,CASE WHEN 1 = 0 THEN C.REPOFFICE_EN_NAME ELSE NULL END AS REPOFFICE_EN_NAME,CASE WHEN 1 = 0 THEN C.OFFICE_CODE ELSE NULL END AS OFFICE_CODE,CASE WHEN 1 = 0 THEN C.OFFICE_CN_NAME ELSE NULL END AS OFFICE_CN_NAME,CASE WHEN 1 = 0 THEN C.OFFICE_EN_NAME ELSE NULL END AS OFFICE_EN_NAME,CASE WHEN 1 = 0 THEN C.REGION_CUSTCATG_CODE ELSE NULL END AS REGION_CUSTCATG_CODE,CASE WHEN 1 = 0 THEN C.REGION_CUSTCATG_CN_NAME ELSE NULL END AS REGION_CUSTCATG_CN_NAME,CASE WHEN 1 = 0 THEN C.REGION_CUSTCATG_EN_NAME ELSE NULL END AS REGION_CUSTCATG_EN_NAME,CASE WHEN 1 = 0 THEN C.TOP_CUST_CATEGORY_CODE ELSE NULL END AS TOP_CUST_CATEGORY_CODE,CASE WHEN 1 = 0 THEN C.TOP_CUST_CATEGORY_EN_NAME ELSE NULL END AS TOP_CUST_CATEGORY_EN_NAME,CASE WHEN 1 = 0 THEN C.TOP_CUST_CATEGORY_CN_NAME ELSE NULL END AS TOP_CUST_CATEGORY_CN_NAME,CASE WHEN 1 = 0 THEN C.ACCTCUST_HQ_CODE ELSE NULL END AS ACCTCUST_HQ_CODE,CASE WHEN 1 = 0 THEN C.ACCTCUST_HQ_CN_NAME ELSE NULL END AS ACCTCUST_HQ_CN_NAME,CASE WHEN 1 = 0 THEN C.ACCTCUST_HQ_EN_NAME ELSE NULL END AS ACCTCUST_HQ_EN_NAME,CASE WHEN 1 = 0 THEN C.ACCTCUST_BRANCH_CODE ELSE NULL END AS ACCTCUST_BRANCH_CODE,CASE WHEN 1 = 0 THEN C.ACCTCUST_BRANCH_CN_NAME ELSE NULL END AS ACCTCUST_BRANCH_CN_NAME,CASE WHEN 1 = 0 THEN C.ACCTCUST_BRANCH_EN_NAME ELSE NULL END AS ACCTCUST_BRANCH_EN_NAME,CASE WHEN 1 = 0 THEN C.ACCTCUST_SUBSIDIARY_CODE ELSE NULL END AS ACCTCUST_SUBSIDIARY_CODE,CASE WHEN 1 = 0 THEN C.ACCTCUST_SUBSIDIARY_CN_NAM ELSE NULL END AS ACCTCUST_SUBSIDIARY_CN_NAM,CASE WHEN 1 = 0 THEN C.ACCTCUST_SUBSIDIARY_EN_NAM ELSE NULL END AS ACCTCUST_SUBSIDIARY_EN_NAM,CASE WHEN 1 = 0 THEN C.COUNTRY_CODE ELSE NULL END AS COUNTRY_CODE --新增加入参 ,CASE WHEN 1 = 0 THEN C.COUNTRY_CN_NAME ELSE NULL END AS COUNTRY_CN_NAME --新增加入参 ,CASE WHEN 1 = 0 THEN C.COUNTRY_EN_NAME ELSE NULL END AS COUNTRY_EN_NAME --新增加入参 , SUM(C.AGREE_AMOUNT) AS AGREE_AMOUNT --协议金额 , SUM(C.AGREE_REMAIN_AMOUNT) AS AGREE_REMAIN_AMOUNT --协议剩余金额 , SUM(C.SIGN_AMOUNT) AS SIGN_AMOUNT --可用金额 , SUM(C.USE_AMOUNT) AS USE_AMOUNT --已使用金额 , SUM( CASE WHEN C.DSCT_TYPE = 'VOUCHER' AND NVL( C.EXPIRED_DATE, add_months(C.EFFECTIVE_DATE, C.VALID_MONTH) ) >= to_date(V_DATE, 'yyyymmdd') THEN C.AGREE_REMAIN_AMOUNT WHEN C.DSCT_TYPE in ( 'FOC', 'Volume Based List Price Adjustment', 'One-Time Discount' ) AND C.DSCT_END_DATE >= to_date(V_DATE, 'yyyymmdd') THEN C.EFFECTIVE_TOTAL_AMOUNT ELSE NULL END ) AS NOT_USED_VALID_AMOUNT --未使用金额(有效期外) , SUM( CASE WHEN C.DSCT_TYPE = 'VOUCHER' THEN C.SIGN_AMOUNT ELSE C.EFFECTIVE_TOTAL_AMOUNT END - CASE WHEN C.DSCT_TYPE = 'VOUCHER' THEN C.USE_AMOUNT ELSE C.USED_TOTAL_AMOUNT END - CASE WHEN C.DSCT_TYPE = 'VOUCHER' AND NVL( C.EXPIRED_DATE, add_months(C.EFFECTIVE_DATE, C.VALID_MONTH) ) >= to_date(V_DATE, 'yyyymmdd') THEN C.AGREE_REMAIN_AMOUNT WHEN C.DSCT_TYPE in ( 'FOC', 'Volume Based List Price Adjustment', 'One-Time Discount' ) AND C.DSCT_END_DATE >= to_date(V_DATE, 'yyyymmdd') THEN C.EFFECTIVE_TOTAL_AMOUNT ELSE NULL END ) AS NOT_USED_INVALID_AMOUNT --未使用金额(有效期内) , SUM( CASE WHEN C.DSCT_TYPE = 'VOUCHER' AND C.EXPIRED_DATE >= to_date(substr(V_DATE, 1, 6), 'yyyymm') and C.EXPIRED_DATE <= LAST_DAY(to_date(V_DATE, 'yyyymmdd')) THEN C.SIGN_AMOUNT WHEN C.DSCT_TYPE in ( 'FOC', 'Volume Based List Price Adjustment', 'One-Time Discount' ) AND C.DSCT_START_DATE >= to_date(substr(V_DATE, 1, 6), 'yyyymm') and C.DSCT_START_DATE <= LAST_DAY(to_date(V_DATE, 'yyyymmdd')) THEN C.EFFECTIVE_TOTAL_AMOUNT ELSE NULL END ) AS NEW_SIGN_AMOUNT --本月新增可用金额 , SUM( CASE WHEN C.DSCT_TYPE = 'VOUCHER' AND C.EFFECTIVE_DATE >= to_date(substr(V_DATE, 1, 6), 'yyyymm') and C.EFFECTIVE_DATE <= LAST_DAY(to_date(V_DATE, 'yyyymmdd')) THEN C.USE_AMOUNT WHEN C.DSCT_TYPE in ( 'FOC', 'Volume Based List Price Adjustment', 'One-Time Discount' ) AND C.DSCT_START_DATE >= to_date(substr(V_DATE, 1, 6), 'yyyymm') and C.DSCT_START_DATE <= LAST_DAY(to_date(V_DATE, 'yyyymmdd')) THEN C.USED_TOTAL_AMOUNT ELSE NULL END ) AS NEW_USE_AMOUNT --本月新使用金额 , SUM( CASE WHEN C.DSCT_TYPE = 'VOUCHER' AND C.EXPIRED_DATE < to_date(V_DATE, 'yyyymmdd') THEN C.AGREE_REMAIN_AMOUNT WHEN C.DSCT_TYPE in ( 'FOC', 'Volume Based List Price Adjustment', 'One-Time Discount' ) AND C.DSCT_END_DATE < to_date(V_DATE, 'yyyymmdd') THEN C.EFFECTIVE_TOTAL_AMOUNT ELSE NULL END ) AS EXPIRED_AMOUNT --本月已过期金额 , SUM( CASE WHEN C.DSCT_TYPE = 'VOUCHER' AND C.EXPIRED_DATE BETWEEN to_date(V_DATE, 'yyyymmdd') AND add_months(to_date(V_DATE, 'yyyymmdd'), 6) THEN C.AGREE_REMAIN_AMOUNT WHEN C.DSCT_TYPE in ( 'FOC', 'Volume Based List Price Adjustment', 'One-Time Discount' ) AND C.DSCT_END_DATE BETWEEN to_date(V_DATE, 'yyyymmdd') AND add_months(to_date(V_DATE, 'yyyymmdd'), 6) THEN C.EFFECTIVE_TOTAL_AMOUNT ELSE NULL END ) AS IMMED_EXPIRED_AMOUNT --半年内即将过期金额 FROM DMSALESW.DM_SALE_BUSI_DSCT_SUM_F C WHERE C.CURRENCY_CODE IN ('USD') --改为多值 AND C.BG_CODE IN ('PDCG901159') AND C.M_ID IN ( 'BUSI_DSCT_00001', 'BUSI_DSCT_00002', 'BUSI_DSCT_00003', 'BUSI_DSCT_00004', 'BUSI_DSCT_00005', 'BUSI_DSCT_00006', 'BUSI_DSCT_00007' ) --新增加字段 --AND C.M_CN IN ('#[#P_REPORT_ITEM_NAME#]#') --新增加字段 --新增加字段 GROUP BY 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36 ) T --新增加入参 下面是执行计划: id | operation | A-time | A-rows | E-rows | E-distinct | Peak Memory | E-memory | A-width | E-width | E-costs ----+-------------------------------------------------------------------------+----------------------+---------+---------+------------+----------------+----------+-----------+---------+----------- 1 | -> Row Adapter | 1139.637 | 7 | 245 | | 419KB | | | 1318 | 117002.27 2 | -> Vector Streaming (type: GATHER) | 1139.616 | 7 | 245 | | 777KB | | | 1318 | 117002.27 3 | -> Vector Subquery Scan on t | [1129.463, 1130.072] | 7 | 245 | | [504KB, 504KB] | 1MB | | 1318 | 116920.22 4 | -> Vector Hash Aggregate | [1129.459, 1130.067] | 7 | 245 | | [4MB, 4MB] | 16MB | [0,898] | 523 | 116920.07 5 | -> Vector Streaming(type: REDISTRIBUTE) | [1129.142, 1129.918] | 112 | 3920 | | [1MB, 1MB] | 2MB | | 523 | 116643.28 6 | -> Vector Hash Aggregate | [882.194, 987.474] | 112 | 3920 | | [8MB, 8MB] | 16MB | [861,861] | 523 | 116498.95 7 | -> CStore Scan on dmsalesw.dm_sale_busi_dsct_sum_f c | [126.343, 142.697] | 3080954 | 2135243 | | [5MB, 5MB] | 1MB | | 203 | 66116.77 可以看到,不但省去了Nest Loop的耗时,而且后面Aggregate的耗时也减少了不少。整体从3s+优化到1.2s。 点击关注,第一时间了解华为云新鲜技术~

优秀的个人博客,低调大师

数仓性能优化:倾斜优化-表达式计算倾斜的hint优化

本文分享自华为云社区《GaussDB(DWS)性能调优:倾斜优化-表达式计算倾斜的hint优化》,作者: 譡里个檔 。 1.原始SQL SELECT TMP4.TAX_AMT, CATE.L1_PUR_ITEM_CATG_CN_NAME || '-' || CATE.L2_PUR_ITEM_CATG_CN_NAME || '-' || CATE.L3_PUR_ITEM_CATG_CN_NAME AS PRODUCT_CATEGORY, MATE.ITEM_CODE AS PRODUCT_CODE, INVEN.INVENTORY_ORG_NAME, TMP4.INVOICE_WITHHOLDING_TAX_GROUP, TMP4.PAYMENT_WITHHOLDING_TAX_GROUP, TMP4.PO_CHARGE_ACCOUNT_CODE, TMP4.CFS_INVOICE_NUMBER, APR.TAX_INVOICE_DATE FROM DWLTAX.DWL_TAX_TAXDP_ERP_AP_INVOICE_TMP5 TMP4, DWRDIM_DW1.DWR_DIM_PUR_ITEM_CATEGORY_D CATE, DWRDIM_DW1.DWR_DIM_MATERIAL_CODE_D MATE, DWRDIM_DW1.DWR_DIM_INVENTORY_ORG_D INVEN, DWTAXDI.DWI_AP_INVOICE_I AP, DWTAXDI.DWI_AP_INVOICE_REGSTN_I APR WHERE 1 = 1 AND TMP4.ITEM_CATEGORY_KEY = CATE.PUR_ITEM_CATG_KEY(+) AND CATE.DEL_FLAG(+) = 'N' AND TMP4.ITEM_ID = MATE.ITEM_ID(+) AND MATE.DEL_FLAG(+) = 'N' AND TMP4.PO_SHIPMENT_TARGET_INV_ORG_KEY = INVEN.INVENTORY_ORG_KEY(+) AND INVEN.DEL_FLAG(+) = 'N' AND TMP4.AP_INVOICE_ID = AP.AP_INVOICE_ID(+) AND 6600 || AP.ATTRIBUTE1 = TO_CHAR(APR.AP_INVOICE_REGSTN_ID(+)) 执行performance,查询具体执行情况和SQL自诊断信息(详细见附件case-step1-原始执行信息.txt) id | operation | A-time | A-rows | E-rows | E-distinct | Peak Memory | E-memory | A-width | E-width | E-costs ----+------------------------------------------------------------------------------------------------------+------------------------+------------+------------+------------+----------------+----------------+-----------+---------+------------- 1 | -> Row Adapter | 69922.773 | 69237018 | 69237018 | | 87KB | | | 573 | 15160857.61 2 | -> Vector Streaming (type: GATHER) | 65581.989 | 69237018 | 69237018 | | 536KB | | | 573 | 15160857.61 3 | -> Vector Hash Right Join (4, 6) | [61186.201, 73129.055] | 69237018 | 69237018 | | [306MB, 682MB] | 1113MB(9990MB) | | 573 | 15159431.83 4 | -> Vector Streaming(type: BROADCAST ng: LC_DL1->LC_DW1) | [554.217, 21008.078] | 1382000544 | 1381572384 | 282184 | [4MB, 4MB] | 3MB | | 16 | 7056095.88 5 | -> CStore Scan on dwifin.dwi_ap_invoice_regstn s | [5.354, 11.617] | 28791678 | 28782758 | | [1MB, 1MB] | 1MB | | 16 | 28004.18 6 | -> Vector Hash Left Join (7, 19) | [1728.008, 2017.488] | 69237018 | 69237018 | 79721 | [834KB, 834KB] | 16MB | [229,252] | 578 | 1832322.90 7 | -> Vector Hash Left Join (8, 17) | [1428.799, 1925.653] | 69237018 | 69237018 | 179 | [32MB, 32MB] | 28MB(8901MB) | | 576 | 1817105.07 8 | -> Vector Streaming(type: PART REDISTRIBUTE PART ROUNDROBIN) | [996.780, 1635.826] | 69237018 | 69237018 | 4167 | [1MB, 1MB] | 2MB | | 570 | 1788113.85 9 | -> Vector Hash Left Join (10, 14) | [1086.903, 1780.641] | 69237018 | 69237018 | | [173MB, 174MB] | 227MB(9067MB) | | 570 | 1304897.12 10 | -> Vector Streaming(type: PART REDISTRIBUTE PART ROUNDROBIN) | [153.628, 891.680] | 69237018 | 69237018 | 20271 | [1MB, 1MB] | 2MB | | 567 | 847160.16 11 | -> Vector Hash Left Join (12, 13) | [367.155, 465.821] | 69237018 | 69237018 | | [30MB, 30MB] | 22MB(8896MB) | | 567 | 363943.43 12 | -> CStore Scan on dwltax.dwl_tax_taxdp_erp_ap_invoice_tmp5 tmp4 | [150.676, 178.827] | 69237018 | 69237018 | 526 | [4MB, 4MB] | 1MB | | 553 | 340168.44 13 | -> CStore Scan on dwrdim_dw1.dwr_dim_pur_item_category_d cate | [14.549, 24.399] | 8228448 | 8228448 | 171426 | [2MB, 2MB] | 1MB | [104,104] | 26 | 9056.99 14 | -> Vector Streaming(type: PART REDISTRIBUTE PART BROADCAST ng: LC_DL1->LC_DW1) | [315.926, 339.782] | 117191217 | 117191170 | 2441483 | [1MB, 1MB] | 3MB | [47,47] | 22 | 406136.10 15 | -> Vector Partition Iterator | [118.307, 151.248] | 117191170 | 117191170 | | [41KB, 41KB] | 1MB | | 22 | 300641.93 16 | -> Partitioned CStore Scan on dwifin.dwi_ap_invoice s | [86.557, 111.947] | 117191170 | 117191170 | | [6MB, 6MB] | 1MB | | 22 | 300641.93 17 | -> Vector Streaming(type: PART LOCAL PART BROADCAST) | [60.429, 99.381] | 15442613 | 15442566 | 321720 | [584KB, 584KB] | 2MB | [58,58] | 19 | 49578.19 18 | -> CStore Scan on dwrdim_dw1.dwr_dim_material_code_d mate | [19.779, 33.206] | 15442566 | 15442566 | | [1MB, 2MB] | 1MB | | 19 | 35704.02 19 | -> CStore Scan on dwrdim_dw1.dwr_dim_inventory_org_d inven | [0.383, 0.739] | 135072 | 135072 | 2814 | [1MB, 1MB] | 1MB | [53,53] | 14 | 2823.85 SQL Diagnostic Information -------------------------------------------------------------------------------------------- Execute diagnostic information PlanNode[4] Large Table in Broadcast "Vector Streaming(type: BROADCAST ng: LC_DL1->LC_DW1)" Predicate Information (identified by plan id) ------------------------------------------------------------------------------------------------------------------------------ 3 --Vector Hash Right Join (4, 6) Hash Cond: (((numeric_out(s.ap_invoice_regstn_id))::character varying)::text = ('6600'::text || (s.attribute1)::text)) 6 --Vector Hash Left Join (7, 19) Hash Cond: (tmp4.po_shipment_target_inv_org_key = inven.inventory_org_key) 7 --Vector Hash Left Join (8, 17) Hash Cond: (tmp4.item_id = mate.item_id) Skew Join Optimized by Statistic 8 --Vector Streaming(type: PART REDISTRIBUTE PART ROUNDROBIN) Skew Filter(type: ROUNDROBIN): ((tmp4.item_id = (-999999)::numeric) OR (tmp4.item_id IS NULL)) 9 --Vector Hash Left Join (10, 14) Hash Cond: (tmp4.ap_invoice_id = s.ap_invoice_id) Skew Join Optimized by Statistic 10 --Vector Streaming(type: PART REDISTRIBUTE PART ROUNDROBIN) Skew Filter(type: ROUNDROBIN): (tmp4.ap_invoice_id = 1001113812002::numeric) 11 --Vector Hash Left Join (12, 13) Hash Cond: (tmp4.item_category_key = cate.pur_item_catg_key) 13 --CStore Scan on dwrdim_dw1.dwr_dim_pur_item_category_d cate Filter: ((cate.del_flag)::text = 'N'::text) Pushdown Predicate Filter: ((cate.del_flag)::text = 'N'::text) 14 --Vector Streaming(type: PART REDISTRIBUTE PART BROADCAST ng: LC_DL1->LC_DW1) Skew Filter(type: BROADCAST): (s.ap_invoice_id = 1001113812002::numeric) 15 --Vector Partition Iterator Iterations: 147 16 --Partitioned CStore Scan on dwifin.dwi_ap_invoice s Partitions Selected by Static Prune: 1..147 17 --Vector Streaming(type: PART LOCAL PART BROADCAST) Skew Filter(type: BROADCAST): (mate.item_id = (-999999)::numeric) 18 --CStore Scan on dwrdim_dw1.dwr_dim_material_code_d mate Filter: ((mate.del_flag)::text = 'N'::text) Pushdown Predicate Filter: ((mate.del_flag)::text = 'N'::text) 19 --CStore Scan on dwrdim_dw1.dwr_dim_inventory_org_d inven Filter: ((inven.del_flag)::text = 'N'::text) Pushdown Predicate Filter: ((inven.del_flag)::text = 'N'::text) 2.禁止大表广播 如上小节显示确实是id=4的这一步是一个大的结果集(2879w条)做了broadcast,并且紧接着的id=5的HashJoin耗时很长。因此通过增加hint方式禁止dwifin.dwi_ap_invoice_regstn走广播。分析发现表dwifin.dwi_ap_invoice_regstn是视图apr展开出现的,因此增加如下hint信息,其中 1. no merge (apr)是防止视图apr中的语句提升,导致的hint信息失效 2. no broadcast(apr)表示禁止apr走broadcast EXPLAIN performance SELECT /*+ no merge (apr) no broadcast(apr) */ TMP4.TAX_AMT, CATE.L1_PUR_ITEM_CATG_CN_NAME || '-' || CATE.L2_PUR_ITEM_CATG_CN_NAME || '-' || CATE.L3_PUR_ITEM_CATG_CN_NAME AS PRODUCT_CATEGORY, MATE.ITEM_CODE AS PRODUCT_CODE, INVEN.INVENTORY_ORG_NAME, TMP4.INVOICE_WITHHOLDING_TAX_GROUP, TMP4.PAYMENT_WITHHOLDING_TAX_GROUP, TMP4.PO_CHARGE_ACCOUNT_CODE, TMP4.CFS_INVOICE_NUMBER, APR.TAX_INVOICE_DATE FROM DWLTAX.DWL_TAX_TAXDP_ERP_AP_INVOICE_TMP5 TMP4, DWRDIM_DW1.DWR_DIM_PUR_ITEM_CATEGORY_D CATE, DWRDIM_DW1.DWR_DIM_MATERIAL_CODE_D MATE, DWRDIM_DW1.DWR_DIM_INVENTORY_ORG_D INVEN, DWTAXDI.DWI_AP_INVOICE_I AP, DWTAXDI.DWI_AP_INVOICE_REGSTN_I APR WHERE 1 = 1 AND TMP4.ITEM_CATEGORY_KEY = CATE.PUR_ITEM_CATG_KEY(+) AND CATE.DEL_FLAG(+) = 'N' AND TMP4.ITEM_ID = MATE.ITEM_ID(+) AND MATE.DEL_FLAG(+) = 'N' AND TMP4.PO_SHIPMENT_TARGET_INV_ORG_KEY = INVEN.INVENTORY_ORG_KEY(+) AND INVEN.DEL_FLAG(+) = 'N' AND TMP4.AP_INVOICE_ID = AP.AP_INVOICE_ID(+) AND 6600 || AP.ATTRIBUTE1 = TO_CHAR(APR.AP_INVOICE_REGSTN_ID(+)) 获取如上语句的performance信息(详细见附件 case-step2-禁止大表广播.txt) id | operation | A-time | A-rows | E-rows | E-distinct | Peak Memory | E-memory | A-width | E-width | E-costs ----+---------------------------------------------------------------------------------------------------------+------------------------+-----------+-----------+------------+----------------+----------------+-----------+---------+------------- 1 | -> Row Adapter | 15685.781 | 69237018 | 69237018 | | 87KB | | | 573 | 33341721.22 2 | -> Vector Streaming (type: GATHER) | 11361.740 | 69237018 | 69237018 | | 536KB | | | 573 | 33341721.22 3 | -> Vector Hash Left Join (4, 19) | [15269.267, 18985.791] | 69237018 | 69237018 | | [74MB, 74MB] | 101MB(9984MB) | | 573 | 33340295.43 4 | -> Vector Streaming(type: REDISTRIBUTE) | [4743.867, 18632.182] | 69237018 | 69237018 | 79721 | [1MB, 2MB] | 2MB | | 578 | 29821930.76 5 | -> Vector Hash Left Join (6, 18) | [1473.990, 15359.055] | 69237018 | 69237018 | | [866KB, 898KB] | 16MB | | 578 | 1832322.90 6 | -> Vector Hash Left Join (7, 16) | [1130.814, 15223.646] | 69237018 | 69237018 | 179 | [32MB, 32MB] | 28MB(9923MB) | | 576 | 1817105.07 7 | -> Vector Streaming(type: PART REDISTRIBUTE PART ROUNDROBIN) | [681.709, 14909.424] | 69237018 | 69237018 | 4167 | [1MB, 1MB] | 2MB | | 570 | 1788113.85 8 | -> Vector Hash Left Join (9, 13) | [1049.201, 12602.796] | 69237018 | 69237018 | | [173MB, 174MB] | 227MB(10089MB) | | 570 | 1304897.12 9 | -> Vector Streaming(type: PART REDISTRIBUTE PART ROUNDROBIN) | [128.704, 11737.099] | 69237018 | 69237018 | 20271 | [1MB, 1MB] | 2MB | | 567 | 847160.16 10 | -> Vector Hash Left Join (11, 12) | [368.537, 443.623] | 69237018 | 69237018 | | [30MB, 30MB] | 22MB(9918MB) | | 567 | 363943.43 11 | -> CStore Scan on dwltax.dwl_tax_taxdp_erp_ap_invoice_tmp5 tmp4 | [148.366, 175.347] | 69237018 | 69237018 | 526 | [4MB, 4MB] | 1MB | | 553 | 340168.44 12 | -> CStore Scan on dwrdim_dw1.dwr_dim_pur_item_category_d cate | [13.319, 24.442] | 8228448 | 8228448 | 171426 | [2MB, 2MB] | 1MB | [104,104] | 26 | 9056.99 13 | -> Vector Streaming(type: PART REDISTRIBUTE PART BROADCAST ng: LC_DL1->LC_DW1) | [242.053, 294.233] | 117191217 | 117191170 | 2441483 | [1MB, 1MB] | 3MB | [47,47] | 22 | 406136.10 14 | -> Vector Partition Iterator | [118.124, 154.954] | 117191170 | 117191170 | | [41KB, 41KB] | 1MB | | 22 | 300641.93 15 | -> Partitioned CStore Scan on dwifin.dwi_ap_invoice s | [86.942, 105.441] | 117191170 | 117191170 | | [6MB, 6MB] | 1MB | | 22 | 300641.93 16 | -> Vector Streaming(type: PART LOCAL PART BROADCAST) | [83.793, 117.853] | 15442613 | 15442566 | 321720 | [584KB, 584KB] | 2MB | [58,58] | 19 | 49578.19 17 | -> CStore Scan on dwrdim_dw1.dwr_dim_material_code_d mate | [21.898, 35.895] | 15442566 | 15442566 | | [1MB, 2MB] | 1MB | | 19 | 35704.02 18 | -> CStore Scan on dwrdim_dw1.dwr_dim_inventory_org_d inven | [0.389, 0.661] | 135072 | 135072 | 2814 | [1MB, 1MB] | 1MB | [53,53] | 14 | 2823.85 19 | -> Vector Streaming(type: REDISTRIBUTE ng: LC_DL1->LC_DW1) | [30.667, 49.474] | 28791678 | 28782758 | 599641 | [2MB, 2MB] | 3MB | [75,75] | 16 | 56030.49 20 | -> Vector Subquery Scan on apr | [42.087, 61.734] | 28791678 | 28782758 | | [376KB, 376KB] | 1MB | | 16 | 30826.02 21 | -> CStore Scan on dwifin.dwi_ap_invoice_regstn s | [5.177, 8.049] | 28791678 | 28782758 | | [1MB, 1MB] | 1MB | | 16 | 28004.18 SQL Diagnostic Information ---------------------------------------------------------------------------------------------------------- Execute diagnostic information PlanNode[4] DataSkew:"Vector Streaming(type: REDISTRIBUTE)", min_dn_tuples:257082, max_dn_tuples:47206637 Predicate Information (identified by plan id) ---------------------------------------------------------------------------------------------------------------------------------- 3 --Vector Hash Left Join (4, 19) Hash Cond: ((('6600'::text || (s.attribute1)::text)) = ((numeric_out(apr.ap_invoice_regstn_id))::character varying)::text) 5 --Vector Hash Left Join (6, 18) Hash Cond: (tmp4.po_shipment_target_inv_org_key = inven.inventory_org_key) 6 --Vector Hash Left Join (7, 16) Hash Cond: (tmp4.item_id = mate.item_id) Skew Join Optimized by Statistic 7 --Vector Streaming(type: PART REDISTRIBUTE PART ROUNDROBIN) Skew Filter(type: ROUNDROBIN): ((tmp4.item_id = (-999999)::numeric) OR (tmp4.item_id IS NULL)) 8 --Vector Hash Left Join (9, 13) Hash Cond: (tmp4.ap_invoice_id = s.ap_invoice_id) Skew Join Optimized by Statistic 9 --Vector Streaming(type: PART REDISTRIBUTE PART ROUNDROBIN) Skew Filter(type: ROUNDROBIN): (tmp4.ap_invoice_id = 1001113812002::numeric) 10 --Vector Hash Left Join (11, 12) Hash Cond: (tmp4.item_category_key = cate.pur_item_catg_key) 12 --CStore Scan on dwrdim_dw1.dwr_dim_pur_item_category_d cate Filter: ((cate.del_flag)::text = 'N'::text) Pushdown Predicate Filter: ((cate.del_flag)::text = 'N'::text) 13 --Vector Streaming(type: PART REDISTRIBUTE PART BROADCAST ng: LC_DL1->LC_DW1) Skew Filter(type: BROADCAST): (s.ap_invoice_id = 1001113812002::numeric) 14 --Vector Partition Iterator Iterations: 147 15 --Partitioned CStore Scan on dwifin.dwi_ap_invoice s Partitions Selected by Static Prune: 1..147 16 --Vector Streaming(type: PART LOCAL PART BROADCAST) Skew Filter(type: BROADCAST): (mate.item_id = (-999999)::numeric) 17 --CStore Scan on dwrdim_dw1.dwr_dim_material_code_d mate Filter: ((mate.del_flag)::text = 'N'::text) Pushdown Predicate Filter: ((mate.del_flag)::text = 'N'::text) 18 --CStore Scan on dwrdim_dw1.dwr_dim_inventory_org_d inven Filter: ((inven.del_flag)::text = 'N'::text) Pushdown Predicate Filter: ((inven.del_flag)::text = 'N'::text) 3.表达式倾斜的hint 发现自诊断信息中倾斜告警 而Plan ID为4的算子是 其中是s是视图dwtaxdi.dwi_ap_invoice_i展开后的表dwifin.dwi_ap_invoice,查询此表的列attribute1的统计信息如下,发现在NULL值上存在严重倾斜 因为重分布列是一个表达式6600 || AP.ATTRIBUTE1,当前DWS的倾斜的hint不支持表达式,因为我们做如下变通实现表达式的值倾斜的hint SELECT /*+ no merge (apr) no broadcast(apr) no merge(ap) skew(ap (attr1) ('6600')) */ TMP4.TAX_AMT, CATE.L1_PUR_ITEM_CATG_CN_NAME || '-' || CATE.L2_PUR_ITEM_CATG_CN_NAME || '-' || CATE.L3_PUR_ITEM_CATG_CN_NAME AS PRODUCT_CATEGORY, MATE.ITEM_CODE AS PRODUCT_CODE, INVEN.INVENTORY_ORG_NAME, TMP4.INVOICE_WITHHOLDING_TAX_GROUP, TMP4.PAYMENT_WITHHOLDING_TAX_GROUP, TMP4.PO_CHARGE_ACCOUNT_CODE, TMP4.CFS_INVOICE_NUMBER, APR.TAX_INVOICE_DATE FROM DWLTAX.DWL_TAX_TAXDP_ERP_AP_INVOICE_TMP5 TMP4, DWRDIM_DW1.DWR_DIM_PUR_ITEM_CATEGORY_D CATE, DWRDIM_DW1.DWR_DIM_MATERIAL_CODE_D MATE, DWRDIM_DW1.DWR_DIM_INVENTORY_ORG_D INVEN, (SELECT *, 6600 || AP.ATTRIBUTE1 AS ATTR1 FROM DWTAXDI.DWI_AP_INVOICE_I AP) AP, DWTAXDI.DWI_AP_INVOICE_REGSTN_I APR WHERE 1 = 1 AND TMP4.ITEM_CATEGORY_KEY = CATE.PUR_ITEM_CATG_KEY(+) AND CATE.DEL_FLAG(+) = 'N' AND TMP4.ITEM_ID = MATE.ITEM_ID(+) AND MATE.DEL_FLAG(+) = 'N' AND TMP4.PO_SHIPMENT_TARGET_INV_ORG_KEY = INVEN.INVENTORY_ORG_KEY(+) AND INVEN.DEL_FLAG(+) = 'N' AND TMP4.AP_INVOICE_ID = AP.AP_INVOICE_ID(+) AND ATTR1 = TO_CHAR(APR.AP_INVOICE_REGSTN_ID(+)) 其中构建了子查询 AP SELECT *, 6600 || AP.ATTRIBUTE1 AS ATTR1 FROM DWTAXDI.DWI_AP_INVOICE_I AP 在把原始的关联列表达式放到子查询里面,然后把 6600 || AP.ATTRIBUTE1 命名为attr1。 在父查询中首先禁止AP这个子查询提升。然后在父查询中通过hint 子查询AP这个结果集的列attr1存在倾斜值'6600' 。这个倾斜值是计算出来的(NULL || 6600 = ‘6600’),并且在原始关联计算中关联表达式是如下,即 6600 || AP.ATTRIBUTE1的结果被转换为text类型(字符串类型) 获取新的语句的performance如下(详细见附件 case-step3-倾斜优化.txt) id | operation | A-time | A-rows | E-rows | E-distinct | Peak Memory | E-memory | A-width | E-width | E-costs ----+------------------------------------------------------------------------------------------------------+-----------------------+-----------+-----------+------------+----------------+----------------+-----------+---------+------------ 1 | -> Row Adapter | 9045.793 | 69237018 | 69237018 | | 87KB | | | 573 | 2040755.71 2 | -> Vector Streaming (type: GATHER) | 4842.656 | 69237018 | 69237018 | | 520KB | | | 573 | 2040755.71 3 | -> Vector Hash Left Join (4, 21) | [2673.707, 11389.688] | 69237018 | 69237018 | | [1MB, 1MB] | 16MB | | 573 | 2039329.92 4 | -> Vector Hash Left Join (5, 19) | [1951.482, 10931.220] | 69237018 | 69237018 | 179 | [32MB, 32MB] | 28MB(10018MB) | | 571 | 2009687.71 5 | -> Vector Streaming(type: PART REDISTRIBUTE PART ROUNDROBIN) | [1541.777, 10591.702] | 69237018 | 69237018 | 4167 | [1MB, 1MB] | 2MB | | 565 | 1980696.49 6 | -> Vector Hash Left Join (7, 18) | [1703.438, 1980.655] | 69237018 | 69237018 | | [30MB, 30MB] | 22MB(10010MB) | | 565 | 1497479.76 7 | -> Vector Hash Left Join (8, 10) | [1523.277, 1708.622] | 69237018 | 69237018 | 526 | [165MB, 166MB] | 191MB(10151MB) | | 551 | 1473704.77 8 | -> Vector Streaming(type: PART REDISTRIBUTE PART ROUNDROBIN) | [94.501, 203.619] | 69237018 | 69237018 | 20271 | [1MB, 1MB] | 2MB | | 553 | 823385.17 9 | -> CStore Scan on dwltax.dwl_tax_taxdp_erp_ap_invoice_tmp5 tmp4 | [142.734, 171.486] | 69237018 | 69237018 | | [4MB, 4MB] | 1MB | | 553 | 340168.44 10 | -> Vector Streaming(type: PART REDISTRIBUTE PART BROADCAST ng: LC_DL1->LC_DW1) | [811.192, 853.583] | 117191217 | 117191170 | 2441483 | [2MB, 2MB] | 3MB | [44,44] | 17 | 598718.74 11 | -> Vector Hash Left Join (12, 15) | [340.998, 790.399] | 117191170 | 117191170 | | [39MB, 39MB] | 27MB(10015MB) | | 17 | 493224.57 12 | -> Vector Streaming(type: PART REDISTRIBUTE PART ROUNDROBIN) | [53.170, 79.836] | 117191170 | 117191170 | 79721 | [2MB, 2MB] | 3MB | | 41 | 412662.90 13 | -> Vector Partition Iterator | [145.450, 171.527] | 117191170 | 117191170 | | [41KB, 41KB] | 1MB | | 22 | 303514.27 14 | -> Partitioned CStore Scan on dwifin.dwi_ap_invoice s | [112.099, 134.193] | 117191170 | 117191170 | | [6MB, 6MB] | 1MB | | 22 | 300641.93 15 | -> Vector Streaming(type: PART REDISTRIBUTE PART BROADCAST) | [48.632, 99.230] | 28791678 | 28782758 | 282184 | [2MB, 2MB] | 3MB | [75,75] | 16 | 56928.04 16 | -> Vector Subquery Scan on apr | [41.916, 78.189] | 28791678 | 28782758 | | [376KB, 376KB] | 1MB | | 16 | 30826.02 17 | -> CStore Scan on dwifin.dwi_ap_invoice_regstn s | [5.233, 10.667] | 28791678 | 28782758 | | [1MB, 1MB] | 1MB | | 16 | 28004.18 18 | -> CStore Scan on dwrdim_dw1.dwr_dim_pur_item_category_d cate | [12.065, 20.667] | 8228448 | 8228448 | 171426 | [2MB, 2MB] | 1MB | [104,104] | 26 | 9056.99 19 | -> Vector Streaming(type: PART LOCAL PART BROADCAST) | [67.272, 97.378] | 15442613 | 15442566 | 321720 | [584KB, 584KB] | 2MB | [58,58] | 19 | 49578.19 20 | -> CStore Scan on dwrdim_dw1.dwr_dim_material_code_d mate | [18.605, 31.713] | 15442566 | 15442566 | | [1MB, 2MB] | 1MB | | 19 | 35704.02 21 | -> CStore Scan on dwrdim_dw1.dwr_dim_inventory_org_d inven | [0.378, 0.647] | 135072 | 135072 | 2814 | [1MB, 1MB] | 1MB | [53,53] | 14 | 2823.85 Predicate Information (identified by plan id) ---------------------------------------------------------------------------------------------------------------------------------- 3 --Vector Hash Left Join (4, 21) Hash Cond: (tmp4.po_shipment_target_inv_org_key = inven.inventory_org_key) 4 --Vector Hash Left Join (5, 19) Hash Cond: (tmp4.item_id = mate.item_id) Skew Join Optimized by Statistic 5 --Vector Streaming(type: PART REDISTRIBUTE PART ROUNDROBIN) Skew Filter(type: ROUNDROBIN): ((tmp4.item_id = (-999999)::numeric) OR (tmp4.item_id IS NULL)) 6 --Vector Hash Left Join (7, 18) Hash Cond: (tmp4.item_category_key = cate.pur_item_catg_key) 7 --Vector Hash Left Join (8, 10) Hash Cond: (tmp4.ap_invoice_id = s.ap_invoice_id) Skew Join Optimized by Statistic 8 --Vector Streaming(type: PART REDISTRIBUTE PART ROUNDROBIN) Skew Filter(type: ROUNDROBIN): (tmp4.ap_invoice_id = 1001113812002::numeric) 10 --Vector Streaming(type: PART REDISTRIBUTE PART BROADCAST ng: LC_DL1->LC_DW1) Skew Filter(type: BROADCAST): (s.ap_invoice_id = 1001113812002::numeric) 11 --Vector Hash Left Join (12, 15) Hash Cond: ((('6600'::text || (s.attribute1)::text)) = ((numeric_out(apr.ap_invoice_regstn_id))::character varying)::text) Skew Join Optimized by Hint 12 --Vector Streaming(type: PART REDISTRIBUTE PART ROUNDROBIN) Skew Filter(type: ROUNDROBIN): ((('6600'::text || (s.attribute1)::text)) = '6600'::text) 13 --Vector Partition Iterator Iterations: 147 14 --Partitioned CStore Scan on dwifin.dwi_ap_invoice s Partitions Selected by Static Prune: 1..147 15 --Vector Streaming(type: PART REDISTRIBUTE PART BROADCAST) Skew Filter(type: BROADCAST): ((((numeric_out(apr.ap_invoice_regstn_id))::character varying)::text) = '6600'::text) 18 --CStore Scan on dwrdim_dw1.dwr_dim_pur_item_category_d cate Filter: ((cate.del_flag)::text = 'N'::text) Pushdown Predicate Filter: ((cate.del_flag)::text = 'N'::text) 19 --Vector Streaming(type: PART LOCAL PART BROADCAST) Skew Filter(type: BROADCAST): (mate.item_id = (-999999)::numeric) 20 --CStore Scan on dwrdim_dw1.dwr_dim_material_code_d mate Filter: ((mate.del_flag)::text = 'N'::text) Pushdown Predicate Filter: ((mate.del_flag)::text = 'N'::text) 21 --CStore Scan on dwrdim_dw1.dwr_dim_inventory_org_d inven Filter: ((inven.del_flag)::text = 'N'::text) Pushdown Predicate Filter: ((inven.del_flag)::text = 'N'::text) 附件:case-step1-原始执行信息.txt0B 附件:case-step3-倾斜优化.txt862.61KB 附件:case-step2-禁止大表广播.txt0B 点击关注,第一时间了解华为云新鲜技术~

优秀的个人博客,低调大师

应用数仓ODBC前,这些问题你需要先了解一下

摘要:ODBC为解决异构数据库间的数据共享而产生的,现已成为WOSA的主要部分和一种数据库访问接口标准。 本文分享自华为云社区《GaussDB(DWS) ODBC 问题定位指南》,作者: power_gouge 。 用户的应用程序,调用的ODBC的API,其实是由驱动管理器提供的,这个驱动管理器在微软上就是odbcad32(.exe/.dll),在Linux上就是UnixODBC。再由它们来调用ODBC的具体驱动(Gauss、Oracle、TD……)。 所以一般问题基本会出在以下几个方面: 应用加载驱动管理器 驱动管理器加载驱动 驱动连接数据库 一个典型的用户应用程序如下: 问题处理 应用程序加载驱动管理器失败 Windows Windows由于操作系统实现机制的问题,ODBC属于操作系统组件的一部分,除非操作系统损坏,一般不会出现应用程序加载驱动管理器失败;只会出现驱动管理器加载驱动失败。所以这里不再赘述。 Linux Linux上应用程序加载驱动管理器,是指的应用程序依赖于UnixODBC的相关动态库,启动时要将其加载到自己的进程空间中。加载出现问题多表现为在启动时找不到libodbc.so.x/libodbcinst.so.x等库。 解决此问题: 首先确认环境中是否安装了UnixODBC。如果安装了,那么至少会有isql/odbcinst等工具可用。例如可使用which isql这样的命令来确定安装路径。相关的lib库一般会在which isql指定的bin目录的同级目录下,将其添加到LD_LIBRARY_PATH中重启应用程序便可。 export LD_LIBRARY_PATH=/where/unixodbc/installed/lib:$LD_LIBRARY_PATH 特别注意,此语句只影响当前shell会话中的后续命令,其他会话不受影响,特别是后台启动的进程。如果是后台进程,请与应用程序的开发人员确认其运行环境如果修正。 如果确认LD_LIBRARY_PATH已经生效(可以打开/proc/应用程序pid/environ文件确认),依然无法加载libodbc.so.x/libodbcinst.so.x,那么可能是.1或者.2的库的问题。 历史原因,一般的开发环境中,UnixODBC提供的库既可能叫libodbc.so.1也可能叫libodbc.so.2。用户程序可能依赖了.2,但是环境中只有.1;也有可能是存在.2,但是依赖了.1。 解决此问题,只需要在UnixODBC的lib目录下,将不存在的版本建立成软链接,保证.1与.2都存在,这样出问题的机率便会小很多。特别注意,这里强烈建议是建立软链接,而不要拷贝物理文件,不然可能出现一个应用程序进程中,加载了两个导出函数完全相同的.so,这样可能会引起一些比较难定位的启动错误,后文中会讲到。 驱动管理器加载驱动失败 Windows 最常见x86与x64架构不同导致的加载失败;此问题的典型报错为: 在指定的 DSN 中,驱动程序和应用程序之间的体系结构不匹配 此问题可能的原因:在64位程序中使用了32位驱动,或者相反。 在64位系统上: C:\Windows\SysWOW64\odbcad32.exe:这是32位ODBC驱动管理器。 C:\Windows\System32\odbcad32.exe:这是64位ODBC驱动管理器。 使用不同架构的应用程序时,请使用不同的驱动管理器;同时安装不同的驱动类型。 32位系统上只能跑32位程序,也无法安装64位驱动,所以基本不用区分。 如果是64位系统,那么它既支持32位程序,也支持64位程序;如果不能确定应用程序是32还是64,可以使用以下办法: ctrl + shift + esc 打开任务管理器 查看进程列表中某进程后边有没有*32的字样(有就是32位,没有就是64位),如下图:\ Linux 环境中缺少psqlodbcw.so的库 一般这个问题的报错是 [UnixODBC][Driver Manager]Can't open lib 'xxx/xxx/psqlodbcw.so' : file not found. 可能的原因有: odbcinst.ini中配置的路径不正确,最简单的办法是 ls -l 一下这个报错的文件,看看这个是不是真的存在,同时具有执行权限。 依赖的库不存在,此时最简单的办法是ldd 一下这个报错的文件,看看是不是真的缺少库,如果缺少库会出现如下问题: 要处理这个问题,需要将unixodbc的安装目录下的lib,添加到LD_LIBRARY_PATH里,例如: export LD_LIBRARY_PATH=/where/unixodbc/installed/lib:$LD_LIBRARY_PATH 同时,在UnixODBC的安装的lib目录下,看看libodbcinst.so.x后边的后缀是.1还是.2。如果是.2,那么请建立一个软链接,链接到.1,便可以解决此问题。 如果该目录下只有.1的库,没有.2的库,也建议建立一个.2的软链接,防止应用程序依赖于.2,我们依赖于.1,引起冲突。 特别注意,当前会话的LD_LIBRARY_PATH不代表应用程序运行时也是同样的LD_LIBRARY_PATH,必要的时候,与应用程序开发人员对齐。 如果是常驻进程,可以通过如下方法获取到当前进程的环境变量: cd /proc/应用程序PID cat environ 打印出来的结果可能比较乱,耐心看一下;如果内容有误,与应用程序开发人员对齐修改方法。 既有.2又有.1的库,导致重复加载 这种勤快的用户比较少见,但是一旦出现,很难定位,典型的报错信息是: Driver's SQLAllocHandle on SQL_HANDLE_DBC failed 这种情况这时应用与驱动加载的是不同的物理文件,便会导致两套完全同名的函数列表,同时出现在同一个可见域里(UnixODBC的libodbc.so.*的函数导出列表完全一致),产生冲突,无法加载数据库驱动。 解决此问题的办法也比较简单,查看LD_LIBRARY_PATH中的第一个unixodbc的lib目录。在其目录下,缺少.2或.1,建立对应的.2或.1的软链接便可。 连接问题 服务器不可达 典型报错: connect to server failed: no such file or directory 此问题可能的原因: 配置了错误的/不可达的数据库地址,或者端口 请检查数据源配置中的Servername及Port配置项,确认网络是通达的。 服务器监听不正确 如果确认Servername及Port配置正确,请根据资料中listen_addresses参数的配置方法,确保数据库监听了合适的网卡及端口,特别是Servername中指定的网卡地址及LVS的虚拟IP地址。 修改完记得重启数据库,使监听生效。 防火墙及网闸、流控设备 请确认防火墙设置,将数据库的通信端口添加到可信端口中。 如果有网闸、流控设备,请确认一下相关的设置。 此问题一般都是第三方商业产品导致,需要咨询服务/产品提供商相关的策略。 SSL配置不正确 典型报错1: The password-stored method is not supported. 解决办法1: 请将数据源配置中的的sslmode调整至allow及以上级别,允许使用SSL连接。 典型报错2: Server common name "xxxx" does not match host name "xxxxx" 此问题是由于sslmode中使用了全校验(verify-full),它不仅会校验证书,还会校验证书所在的域名/机器名是否与证书符合,不符合时将报出此问题。 解决办法2: 重新让CA机构以新的域名/机器名签发证书;或者将SSLMODE调整至verify-ca选项或其以下级别(具体级别见产品资料中的说明)。 使用开源驱动连接问题 我们的数据库是支持低版本及开源驱动的(V1R7C10及以后),所以可以放心使用。 但是偶尔一些从V1R6C10升级上来的数据库,接受开源驱动连接时,会碰到用户认证算法不支持的问题,典型报错如下: authentication method 10 not supported. 此问题机理比较复杂,下面详细展开,先说解决办法: 请使用管理新账号新建一个数据库的用户,并给予其相关的访问权限,使用新用户连接数据库。 更改当前业务用户的密码,使用新密码连接数据库。 解释一下此问题发生的机理: 我们的数据库在连接时,是会让客户端将认证信息发过来的。但是发过来的信息不会是明文密码,这是不安全的;客户端发到数据库的认证信息一般是经过加盐后的密码哈希(md5/sha256算法),迭代次数也非常多。 数据库本身也并不存储用户的明文密码,存储的是一个哈希值(所以密码要是丢了,就真的丢了,只能重置不能找回)。数据库在校验这个密码的时候,是比较哈希的,这就涉及到数据库中存储的哈希是使用的什么算法得到的哈希值,常见的是sha256(高斯自研)及MD5(开源)。 V1R7C00及以前,数据库中只存储了SHA256的哈希,升级时我们也无法推导用户原有密码,所以升级后仍然只有SHA256的哈希;但是开源客户端只识别MD5的哈希,这就导致数据库无法认证;数据库也只会让客户端以SHA256的哈希来做认证,这时开源就不识别该认证请求,导致报出如上的错误。 在创建用户和修改用户密码时,我们的新版本会同时记录两份哈希,所以后续将会同时支持开源及自研的各个版本。 因数据源配置不正确,导致的连接错误 典型报错: Data source name not found, and no default driver specified 可能原因: 数据源名称书写错误(或含有特殊符号) 不同的操作系统用户下,数据源可见性不一样; Linux上的数据源配置文件(odbc.ini)位置不正确 解决办法: 修正数据源名称. Windows下,请在当前用户下打开驱动管理器,查看数据源配置是否正确。 请注意在64位系统上使用正确的数据源管理器: C:\Windows\SysWOW64\odbcad32.exe:这是32位ODBC驱动管理器。 C:\Windows\System32\odbcad32.exe:这是64位ODBC驱动管理器。 Linux下使用odbcinst -j 命令,查看当前环境中配置文件的正确路径,输出一般如下: unixODBC 2.3.0 DRIVERS............: /usr/local/etc/odbcinst.ini/odbcinst.ini SYSTEM DATA SOURCES: /usr/local/etc/odbcinst.ini/odbc.ini FILE DATA SOURCES..: /usr/local/etc/odbcinst.ini/ODBCDataSources USER DATA SOURCES..: /usr/local/etc/odbc.ini SQLULEN Size.......: 8 SQLLEN Size........: 8 SQLSETPOSIROW Size.: 8 其中USER DATA SOURCES就是用户数据源,优先生效;SYSTEM DATA SOURCES是系统数据源,整个系统可用。请针对这些文件路径, 注意:有时用户数据源的配置文件可能是$(HOME)/.odbc.ini 通信协议不匹配问题 典型报错: unsupported frontend protocol 3.51: server supports 1.0 to 3.0 可能原因: 使用了新版本的数据库驱动连接老版本的数据库(V1R6C10); 或者使用了我们的驱动,连接到了开源的数据库上。 解决办法: 请使用老版本的数据库驱动连接该数据库。 我们的数据库中,默认低版本客户端可以连接高版本数据库;使用高版本驱动连接低版本客户端,不在规格约束范围内。 这个规格也比较好理解:因为用户一般是对数据库集中管理,升级也是有计划的。但是客户端驱动可能嵌入到业务中的每一个角落,有时甚至是已经发布的装备中,升级相对比较困难。 如果是开源服务器:我们的数据库驱动不支持开源数据库,无法连接;请使用开源客户端连接。 其他常见疑问 与开源的区别? 增加了安全性,使用了SHA256算法做认证加密;同时调整密钥哈希加密次数 提升了批量性能(V1R7C10 2019-4-30及以后版本) 是否可以增加新API? 不可以。 还是基础知识里那张图,用户引用的API是由驱动管理器提供的,我们提供的API只可供驱动管理器使用;新增API无法穿过中间层为用户提供服务。 是否支持COPY接口? Copy是PG的特有语法及通信协议;而ODBC是微软提出的通用调用接口,所以无此特殊接口。 Linux上的驱动管理器有哪些? 驱动管理器在Linux上并不是操作系统的一部分,它也是由其他开源组织开发的。所以并不是只有UnixODBC一种。但是目前使用最广泛的,其实只有UnixODBC,多数据操作系统安装时基本都已经自带了UnixODBC的某个特定版本;除此之外,还有iODBC等,现在已经慢慢退出市场了。 UnixODBC的版本有限制么? 有。我们支持2.3.0及以上版本。 UnixODBC的.1与.2的库有什么区别? 没有什么区别。 这个与UnixODBC的历史有关,历史上有一段时间提供.1,后来做了一次大升级,动态库版本也跟着升级了,变成了.2。但是一大批存量业务受制无法运行,就又添加了.1的支持。 .1与.2其实只是UnixODBC的configure配置的一部分,其函数导出,功能完全一致,不必纠结于此。 可以打印日志么? 可以。 一般建议打印驱动管理器的日志,此日志比较清晰,定位问题比较快。操作办法: Windows上: 打开驱动管理器,调整到跟踪页面,确定日志文件路径后,点击开始跟踪便可,如图: Linux上: 打开odbcinst.ini文件(可使用odbcinst -j 来确定文件路径),添加以下章节: [ODBC] Trace=Yes TraceFIle=/tmp/odbc.log 重启业务便可。 注意:非必要时,请关闭日志,因为每个API都存在写盘,将会引起性能损失。 查询结果集过大,内存吃不消怎么办? 打开UseDclareFetch开关,它将会把查询包装成游标操作。对于不支持Cursor with hold的版本慎用。同时由于使用了服务器端的游标,游标的前后滚操作也会反馈给数据库,通信会有所增加,所以性能会有部分下降;可以通过调整Fetch参数来确定每次数据库向客户端反馈的数据量大小,来降低该性能影响。 Linux下打开UseDeclareFetch的方法: 在数据源配置项中添加: UseDeclareFetch=1 Fetch=1000 Windows下打开UseDeclareFetch的方法: 其中的Cache Size选项,就是Fetch的大小。 有性能基线数据么? 创建连接的性能大体为0.5s内都算正常(一般0.3s左右) 数据插入的话 非批量版本(R7C10以及前)大约为400tps(SSD的测试结果) 批量版本(R8C10及以后)大约为4000tps(SSD服务器),由于数据库对象差异、网络、物理硬件等,基本2000tps以上都可以认为是正常 语句出错怎么排查? 运行过程中出错,ODBC是不会打屏的。错误信息需要业务里获取错误信息(API为:SQLGetDiagField/SQLGetDiagRec)。 如果用户的业务里有打印具体的错误信息,或者业务的错误信息不足以定位,请根据3.7中的描述,将ODBC的日志打印出来,在其中找SQL_ERROR相关信息。这里最好能和业务开发人员一起定位,因为API的调用序列是乱序的,由业务决定。 如果ODBC的日志仍然不足以定位支撑,请登录到连接的目标CN所在的机器,通过以下方法进入CN日志文件目录: source ${BIGDATA_HOME}/mppdb/.mppdbgs_profile cd $GAUSSLOG/pg_log/cn_50xx #这里的cn_50xx表示CN编号,根据实际情况修改 找到对应时间点的日志,观察其中是否有错误信息。 我们与Oracle/MYSQL的ODBC有什么关系 ODBC是一套标准,每家数据库提供自己的驱动文件。就像大家都叫显卡,每个厂商也都提供自己的驱动,自己的驱动只能驱动自己的显卡;而显卡的接口标准是微软(ODBC也是微软)制定的,只是大家不接触,不知道有这样一套标准而已。 我们的驱动文件叫psqlodbcw.so/psqlodbcw.dll。 支持GBK么? 支持。 但是我们ODBC驱动默认使用utf-8编码。如果要调整,需要自行在会话开始时设置client_encoding。 但是请注意,请不要在宽字节模式下使用GBK,因为宽字节编码本身就是UNICODE的一部分(一般为UCS2),此时使用GBK可能导致数据无法显示,SQL查询结果不正确等问题。 如果出现此问题,请将VS中的解决方案字符集调整为“多字节”。 文章由博主@归云原创 想了解GuassDB(DWS)更多信息,欢迎微信搜索“GaussDB DWS”关注微信公众号,和您分享最新最全的PB级数仓黑科技,后台还可获取众多学习资料哦~ 点击关注,第一时间了解华为云新鲜技术~

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册