社区版4.3.0.1,group by疑似存在bug

【 使用环境 】测试环境
【 OB or 其他组件 】
【 使用版本 】5.7.25-OceanBase_CE-v4.3.0.1
【问题描述】
如下图所示,select distinct dw_table_name from dw_task_row_id t where t.dw_table_name like ‘SP_UPDATE_COMPLEMENT_GID%’;
查询dw_task_row_id表中dw_table_name字段存在四个以“SP_UPDATE_COMPLEMENT_GID”开头的结果

select dw_table_name,count(1) from dw_task_row_id t where t.dw_table_name like ‘SP_UPDATE_COMPLEMENT_GID%’ group by dw_table_name;
换成group by dw_table_name字段查询时,出现的结果如下,dw_table_name分组后出现两组重复,并且缺少一组数据

ddl如下
CREATE TABLE dw_task_row_id (
dw_table_name varchar(128) NOT NULL COMMENT ‘dw表名’,
end_row_id bigint(20) NOT NULL COMMENT ‘截止行id’,
end_update_time datetime DEFAULT NULL COMMENT ‘截止更新时间’,
PRIMARY KEY (dw_table_name, end_row_id)
) DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = ‘zstd_1.3.8’ REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 COMMENT = ‘DW任务ID表’

【复现路径】
【附件及日志】推荐使用OceanBase敏捷诊断工具obdiag收集诊断信息,详情参见链接(右键跳转查看):

【SOP系列 22 】——故障诊断第一步(自助诊断和诊断信息收集)

【备注】基于 LLM 和开源文档 RAG 的论坛小助手已开放测试,在发帖时输入 [@论坛小助手] 即可召唤小助手,欢迎试用!

推荐使用 obdiag 工具进行日志采集,以便我们能够进一步分析问题的原因。

日志采集场景: SQL性能问题
日志采集命令: obdiag gather scene run --scene=observer.perf_sql --env “{db_connect=’-h127.0.0.1 -P2881 -utest@test -p****** -Dtest’, trace_id=‘Yxx’}”

请您提供一些信息以便我们更好地帮助您:

  1. 您能否提供具体的 SQL 语句以及执行该 SQL 语句的上下文环境?
  2. 您是否可以提供表结构定义(CREATE TABLE 语句)以及索引信息?
  3. 您是否有对该表执行过任何维护操作,例如重建索引或优化表?
  4. 您是否可以提供执行计划(EXPLAIN PLAN)以供我们参考?
  5. 您是否尝试过使用其他方式(如子查询)来实现相同的功能,效果如何?
  6. 您是否可以提供 obdiag 日志采集命令的输出结果压缩包?这将有助于我们更准确地定位问题。

详情请参考:

  1. 概述

附上敏捷诊断工具 obdiag 使用帮助链接

select dw_table_name from dw_task_row_id t where t.dw_table_name like ‘SP_UPDATE_COMPLEMENT_GID%’;
去掉distinct 去重字段呢

一楼有distinct去重的结果

去掉distinct没啥意义吧

根据您提供的信息,SELECT DISTINCTGROUP BY 的查询结果不一致,这确实看起来有些异常。通常情况下,SELECT DISTINCT 应该返回与 GROUP BY 相同的结果集,因为它们都是为了去重。

分析与建议

  1. 检查数据一致性

    • 请确保数据在查询时没有发生变化。可以先锁定表,然后再次运行这两个查询,看看结果是否一致。
    • 您可以尝试在一个事务中执行这两个查询,以确保数据的一致性。
  2. 检查执行计划

    • 使用 EXPLAIN 查看两个查询的执行计划,看看是否有不同的优化策略导致了结果的差异。
    • 例如,EXPLAIN SELECT DISTINCT dw_table_name FROM dw_task_row_id t WHERE t.dw_table_name LIKE 'SP_UPDATE_COMPLEMENT_GID%'EXPLAIN SELECT dw_table_name, COUNT(1) FROM dw_task_row_id t WHERE t.dw_table_name LIKE 'SP_UPDATE_COMPLEMENT_GID%' GROUP BY dw_table_name
  3. 检查索引

    • 确认 dw_table_name 列上有合适的索引。索引的存在可能会影响查询的执行计划。
    • 您可以使用 SHOW INDEX FROM dw_task_row_id 查看索引信息。
  4. 检查数据内容

    • 检查 dw_table_name 列的数据内容,特别是是否有不可见字符或空格导致的差异。
    • 例如,可以使用 SELECT HEX(dw_table_name) FROM dw_task_row_id t WHERE t.dw_table_name LIKE 'SP_UPDATE_COMPLEMENT_GID%' 查看数据的十六进制表示。
  5. 使用 Hint 强制优化器行为

    • 尝试使用 Hint 强制优化器使用特定的算法。例如,使用 /*+ USE_HASH_AGGREGATION *//*+ NO_USE_HASH_AGGREGATION */
    • 例如:
      EXPLAIN SELECT /*+ USE_HASH_AGGREGATION */ DISTINCT dw_table_name FROM dw_task_row_id t WHERE t.dw_table_name LIKE 'SP_UPDATE_COMPLEMENT_GID%';
      EXPLAIN SELECT /*+ USE_HASH_AGGREGATION */ dw_table_name, COUNT(1) FROM dw_task_row_id t WHERE t.dw_table_name LIKE 'SP_UPDATE_COMPLEMENT_GID%' GROUP BY dw_table_name;
      

示例

  1. 检查数据一致性

    START TRANSACTION;
    SELECT DISTINCT dw_table_name FROM dw_task_row_id t WHERE t.dw_table_name LIKE 'SP_UPDATE_COMPLEMENT_GID%';
    SELECT dw_table_name, COUNT(1) FROM dw_task_row_id t WHERE t.dw_table_name LIKE 'SP_UPDATE_COMPLEMENT_GID%' GROUP BY dw_table_name;
    COMMIT;
    
  2. 检查执行计划

    EXPLAIN SELECT DISTINCT dw_table_name FROM dw_task_row_id t WHERE t.dw_table_name LIKE 'SP_UPDATE_COMPLEMENT_GID%';
    EXPLAIN SELECT dw_table_name, COUNT(1) FROM dw_task_row_id t WHERE t.dw_table_name LIKE 'SP_UPDATE_COMPLEMENT_GID%' GROUP BY dw_table_name;
    
  3. 检查索引

    SHOW INDEX FROM dw_task_row_id;
    
  4. 检查数据内容

    SELECT HEX(dw_table_name) FROM dw_task_row_id t WHERE t.dw_table_name LIKE 'SP_UPDATE_COMPLEMENT_GID%';
    
  5. 使用 Hint

    EXPLAIN SELECT /*+ USE_HASH_AGGREGATION */ DISTINCT dw_table_name FROM dw_task_row_id t WHERE t.dw_table_name LIKE 'SP_UPDATE_COMPLEMENT_GID%';
    EXPLAIN SELECT /*+ USE_HASH_AGGREGATION */ dw_table_name, COUNT(1) FROM dw_task_row_id t WHERE t.dw_table_name LIKE 'SP_UPDATE_COMPLEMENT_GID%' GROUP BY dw_table_name;
    

通过这些步骤,您可以更好地了解问题的根源,并采取相应的措施解决问题。如果问题仍然存在,建议联系 OceanBase 的技术支持团队以获得进一步的帮助。

详情请参考:

  1. DISTINCT
  2. 基于规则的查询改写
  3. UNION
  4. Optimizer Hint
  5. SQL 基础操作(MySQL 模式)

(小助手的答复已结束,如未能解决您的问题,请继续提问并等待其他同学的回复,谢谢!)

这个看着有意思了 把主键 dw_table_name , end_row_id 拼接一块分组 看看数据有啥不一样么?是不是数据最后面有空格 造成