PolarDB有个sql能帮忙查下吗 ?

PolarDB有个sql能帮忙查下吗 这个sql用Statement Outline固定了执行计划 正常应该走指定的索引扫描2k多行数据 刚才触发了两次查询扫描了20多w数据 40多秒才查询出来
84e7208d61c38e88ff5d278299ed3ed3.png
SELECT
sdt.produce_id,
sdt.customer_id,
sel.company_name AS company_name_m,
sel.prefix_domain_name,
sdt.products_id,
sdt.products_url_name,
SUBSTR(sdt.category_id, 1, 3) AS category_id_lv1,
sdt.produce_cas_no AS cas_no,
sdt.produce_name,
sdt.produce_url_name,
sdt.goods_picture_s,
sdt.goods_picture_m AS goods_picture,
sdt.goods_picture_b,
sdt.complete_flag,
sdt.hot_flag,
sdt.main_flag,
sdt.grade_name,
sdt.content,
sdt.package_name,
sdt.n_price_type,
sdt.n_price_trade_term_type,
sdt.n_price_trade_term_text,
sdt.n_price,
sdt.n_price_unit,
sdt.n_price_currency,
sdt.n_price_currency_symbol,
CASE
WHEN CEILING(IFNULL(sdt.n_min_price, 0)) = 0 THEN '0'
WHEN sdt.n_price_end_date < CURRENT_DATE() THEN '0'
ELSE '1'
END AS n_pending_flag,
sdt.activity_id,
sdt.activity_type,
sdt.a_price_trade_term_type,
sdt.a_price_trade_term_text,
sdt.a_price,
sdt.a_price_unit,
sdt.a_price_currency,
sdt.a_price_currency_symbol
FROM
t_e_all_produce_v1 sdt
INNER JOIN t_e_all_seller_v1 sel ON sdt.customer_id = sel.customer_id
WHERE
sdt.delflag = '0'
AND sel.delflag = '0'
AND sdt.customer_id = 'us20220607140012825'
AND sdt.products_id = 'pd2005121001'
AND sdt.produce_id != 'pr22121432843'
AND sdt.complete_flag = '1'
ORDER BY
sdt.produce_update_date DESC
limit 6

展开
收起
嘟嘟嘟嘟嘟嘟 2024-05-09 08:40:34 61 分享 版权
阿里云 AI 助理回答

问题分析与解决步骤

根据您提供的SQL语句和描述,该SQL在使用PolarDB的Statement Outline功能固定执行计划后,出现了异常情况:原本应通过指定索引扫描2k多行数据,但实际查询却扫描了20多万行数据,导致查询耗时40多秒。以下是针对此问题的详细分析和解决步骤。


1. 确认Statement Outline是否生效

首先需要确认Statement Outline是否正确应用到该SQL语句上。可以通过以下步骤验证:

1.1 查看匹配情况

使用dbms_outln.preview_outline存储过程检查SQL是否匹配到已定义的Statement Outline规则:

CALL dbms_outln.preview_outline('your_schema_name', "SELECT sdt.produce_id, ...");
  • 如果返回结果为空,则说明当前SQL未匹配到任何Statement Outline规则。
  • 如果返回结果不为空,请检查返回的Hint内容是否符合预期(例如是否指定了正确的索引)。

1.2 检查内存中的命中情况

使用dbms_outln.show_outline查看内存中Statement Outline的命中情况:

CALL dbms_outln.show_outline();
  • 确保目标SQL的Digest值与Statement Outline规则中的Digest值一致。
  • 如果StateN,则表示该规则未启用,需将其状态更新为Y

1.3 验证执行计划

使用EXPLAIN命令查看SQL的实际执行计划,确认是否使用了指定的索引:

EXPLAIN SELECT sdt.produce_id, ...;
  • 如果执行计划中未使用预期的索引扫描(如Index ScanIndex Only Scan),则说明Statement Outline未生效或存在其他问题。

2. 检查索引覆盖与优化器选择

如果Statement Outline已生效,但执行计划仍不符合预期,可能是由于以下原因导致:

2.1 索引覆盖不足

确保SQL中涉及的所有列均被索引覆盖。如果索引未完全覆盖查询条件或排序字段,优化器可能会选择全表扫描或其他非最优路径。

  • 使用dbms_imci.check_columnar_index检查SQL是否被列存索引完全覆盖:
    CALL dbms_imci.check_columnar_index("SELECT sdt.produce_id, ...");
    
    • 如果返回结果包含未覆盖的列,则需要为这些列创建新的索引。

2.2 查询代价评估

优化器可能基于查询代价评估选择了非最优路径。可以通过以下方式强制使用指定索引:

  • 在SQL中添加FORCE INDEX提示:
    SELECT /*+ FORCE INDEX(index_name) */ sdt.produce_id, ...;
    
  • 或者调整优化器参数,降低使用列存索引的代价阈值:
    SET loose_cost_threshold_for_imci = 0;
    

3. 检查数据分布与统计信息

优化器的选择依赖于表的统计信息。如果统计信息过期或不准确,可能导致优化器选择错误的执行计划。

3.1 更新统计信息

使用ANALYZE命令更新表的统计信息:

ANALYZE TABLE t_e_all_produce_v1;
ANALYZE TABLE t_e_all_seller_v1;

3.2 检查数据分布

确认customer_idproducts_id等过滤条件的值是否具有高选择性。如果这些字段的值分布不均匀,可能导致优化器低估索引扫描的效率。


4. 强制转发至列存节点

如果您的PolarDB实例启用了列存节点,但SQL未被转发至列存节点,也可能导致性能问题。

4.1 检查转发配置

确认数据库连接地址中是否包含只读列存节点,并确保loose_cost_threshold_for_imci参数设置合理。

4.2 强制转发

在SQL中添加/*FORCE_IMCI_NODES*/提示,强制将SQL转发至列存节点:

/*FORCE_IMCI_NODES*/ EXPLAIN SELECT sdt.produce_id, ...;

5. 调整Statement Outline规则

如果上述步骤均未解决问题,可以尝试重新定义或调整Statement Outline规则。

5.1 删除现有规则

删除当前的Statement Outline规则:

CALL dbms_outln.del_outline(<Id>);

5.2 添加新的规则

重新添加Statement Outline规则,确保Hint内容明确指定索引:

CALL dbms_outln.add_index_outline(
  'your_schema_name', 
  '', 
  1, 
  'USE INDEX', 
  'index_name', 
  '', 
  "SELECT sdt.produce_id, ..."
);

6. 总结与建议

  • 优先确认Statement Outline是否生效,并检查执行计划是否符合预期。
  • 确保索引覆盖完整,避免因索引不足导致优化器选择全表扫描。
  • 更新统计信息,确保优化器能够准确评估查询代价。
  • 强制转发至列存节点,充分利用列存索引的性能优势。
  • 必要时调整Statement Outline规则,确保其与实际需求一致。

如果问题仍未解决,请提供以下信息以便进一步排查: 1. EXPLAIN输出的完整执行计划。 2. 当前Statement Outline规则的定义(包括Hint内容)。 3. 表的索引结构及统计信息。

希望以上步骤能帮助您快速定位并解决问题!

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答

阿里云关系型数据库主要有以下几种:RDS MySQL版、RDS PostgreSQL 版、RDS SQL Server 版、PolarDB MySQL版、PolarDB PostgreSQL 版、PolarDB分布式版 。

还有其他疑问?
咨询AI助理