关于行列混存问题,跪求各位大神解答

【 使用环境 】生产环境
【 OB 】
【 使用版本 】 V4.3.4
【问题描述】我明明创建了行列混存,WITH COLUMN GROUP(all columns, each column)。加了这条在里面, 我查询的时候走了列存,但是走索引的代价是更低的,是不是加了列存,会导致索引失效,或者说列存是高于索引;然后我尝试了下把列存关掉,查询速度马上上来了,但是诡异的地方来了,就是我把列存开启后,我用语句强制不走列存,但是速度依然和走列存是一样的速度。我的执行语句是:SELECT Ord_id /*+ NO_USE_COLUMN_TABLE(Ord_1129) / FROM Ord_1129 PARTITION(p8) WHERE member_id = 8738 and is_cancel = 0 and is_clear = 0 ORDER BY Ordtime desc,sort asc LIMIT 500 OFFSET 0

已经加了。 /*+ NO_USE_COLUMN_TABLE(Ord_1129) /
【复现路径】问题出现前后相关操作
【附件及日志】、

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

@论坛小助手

您的问题可能存在误解,实际上据我所知,OceanBase 社区版目前并不支持行列混存的功能。OceanBase 是一个分布式的关系型数据库管理系统,它主要支持行存储模式来优化事务处理(OLTP),而列存储模式通常用于优化分析查询(OLAP)。如果您需要同时具备高效的事务处理能力和分析能力,可以考虑使用 OceanBase 的 HTAP(Hybrid Transactional and Analytical Processing)特性,但这并不等同于行列混存。

如果您确实遇到了与行列混存相关的配置或行为问题,建议您检查是否开启了某些特定的实验性功能或者使用了企业版的高级特性。不过,根据您提供的信息,这似乎不太可能是原因。为了更准确地定位问题,您可以提供更多的上下文信息,比如具体的建表语句、执行的 SQL 语句以及任何相关的错误信息或日志记录。这样可以帮助我们更好地理解您的情况,并提供更有针对性的帮助。

更多信息请查看:

  1. 0001 ~ 3999

@论坛小助手

这是加了不走列存,─TABLE FULL SCAN |Ord_1129(idx_betime_sort,Reverse)|37318

根据您提供的信息,您在使用 OceanBase 时遇到了关于行列混存的问题。具体来说,您创建了一个带有列组的表,但在查询时发现即使指定了不使用列存,查询性能也没有显著提升。这里有几个方面可以探讨和解决这个问题:

1. 行列混存的基本概念

在 OceanBase 中,行列混存是一种将行存储和列存储结合的技术,旨在同时优化事务处理(OLTP)和分析查询(OLAP)。您提到的 WITH COLUMN GROUP 语法用于定义列组,这些列组可以被优化器选择使用,以提高查询性能。

2. 查询优化器的行为

查询优化器会根据统计信息和成本估算选择最优的执行计划。即使您指定了 /*+ NO_USE_COLUMN_TABLE(Ord_1129) */,优化器仍然可能会选择全表扫描或其他执行计划,特别是当索引的代价确实更低时。

3. 具体问题分析

根据您提供的执行计划:

─TABLE FULL SCAN       |Ord_1129(idx_betime_sort,Reverse)|37318

这表明优化器选择了全表扫描,并且使用了 idx_betime_sort 索引。这可能是因为:

  • 索引的选择idx_betime_sort 索引可能覆盖了查询所需的大部分列,因此优化器认为全表扫描加上索引扫描的成本更低。
  • 统计信息:优化器依赖于表的统计信息来做出决策。如果统计信息不准确,优化器可能会做出次优的选择。

4. 解决方案

4.1 更新统计信息

确保表的统计信息是最新的,这可以帮助优化器做出更准确的决策。

ANALYZE TABLE Ord_1129;

4.2 检查索引

确保索引覆盖了查询所需的列。如果 idx_betime_sort 索引没有覆盖所有需要的列,可以考虑创建一个覆盖索引。

CREATE INDEX idx_betime_sort_cover ON Ord_1129 (member_id, is_cancel, is_clear, Ordtime, sort, Ord_id);

4.3 强制使用索引

如果确定索引的代价更低,可以尝试强制使用索引。

SELECT Ord_id 
FROM Ord_1129 PARTITION(p8) 
WHERE member_id = 8738 AND is_cancel = 0 AND is_clear = 0 
ORDER BY Ordtime DESC, sort ASC 
LIMIT 500 OFFSET 0 
/*+ USE_INDEX(Ord_1129, idx_betime_sort_cover) */;

4.4 检查执行计划

使用 EXPLAIN 查看详细的执行计划,确保优化器选择了预期的执行计划。

EXPLAIN SELECT Ord_id 
FROM Ord_1129 PARTITION(p8) 
WHERE member_id = 8738 AND is_cancel = 0 AND is_clear = 0 
ORDER BY Ordtime DESC, sort ASC 
LIMIT 500 OFFSET 0 
/*+ NO_USE_COLUMN_TABLE(Ord_1129) */;

5. 总结

  • 更新统计信息:确保优化器有最新的统计信息。
  • 检查索引:确保索引覆盖了查询所需的列。
  • 强制使用索引:如果确定索引的代价更低,可以尝试强制使用索引。
  • 检查执行计划:使用 EXPLAIN 查看详细的执行计划,确保优化器选择了预期的执行计划。

希望这些建议能帮助您解决问题。如果问题仍然存在,建议您联系 OceanBase 的技术支持团队以获得进一步的帮助。

更多信息请查看:

  1. 诊断实践:使用 SQL_PLAN_MONITOR 分析性能问题
  2. 联接顺序
  3. SQL 调优典型场景和案例
  4. 统计信息和估行机制的使用
  5. SECOND
  6. CURTIME
  7. 列存 FAQ
  8. 基于规则的路径选择
  9. TIME_TO_SEC

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

麻烦使用obdiag分别收集下使用列存和不使用列存的sql执行信息

obdiag gather scene run --scene=observer.perf_sql [options]

https://www.oceanbase.com/docs/common-obdiag-cn-1000000001768268