当数据迁移遇到MySql表统计分析(Cardinality)不准确的坑

最近给客户做数据迁移,850W用户的数据,在测试环境进行迁移测试,测试环境配置:红帽,物理机,32核,迁移时间80分钟左右。

生产环境配置:红帽,物理机,40核。

但是在生产上进行迁移时发现特别慢,按照速度预估需要6个小时,然后进行排查,发现数据库CPU占用率比较高,迁移程序耗费CPU不大,而在测试环境正好相反,这会已经基本上定位到问题在数据库这块,然后进过分析猜测是不是由二点问题导致:

1、没加索引

2、数据库碎片

但是进过排查发现都不是,然后我们分析数据库慢SQL发现有一条语句耗时将近2分钟,如下:


然后再次检查索引是加了索引的,然后在查看执行计划,竟然跟测试环境不一样。。。。

测试环境执行计划:


生产环境执行计划:


可以看到环境的d表没有走索引,而是进行了全表扫描。

经过分析发现是MySql的索引统计分析在捣鬼,他预估的索引唯一值Cardinality,还是按原数据进行预估为70W,这次插入了850W,当执行查询的时候,发现重复数据占比70/920=1/13,查询优化器发现重复率太高,放弃走索引,所以导致了全表扫描。

定位到问题以后执行了ANALYZE TABLE ,在测试查看执行计划与测试环境一致,问题解决


事后查资料分析这个问题,发现网上解释都不是特别清楚,有的文章说进行insert或update的时候会触发索引统计分析,经过生产上论证不是完全准确的,因为迁移的时候对d表就会有插入操作,按说法应该更新Cardinality值,但是却没有更新。

而《高性能MySql》书中则描述表的大小超过十六分之一或者新插入20亿行会触发,很明显插入的数据超过十六分之一了,但是还是没有触发,其中书中提及的innodb_stats_sample_pages也进行了查看,与测试环境一样,默认8。

目前短时间只能搁置了,后续了解原理了在更新!









<think>嗯,用户现在问的是ClickHouse的语法和MySQL一样吗。我需要先回想一下之前用户的问题,之前他们问的是Java代码的简化写法,现在转向了数据库语法比较。这可能意味着用户正在处理数据存储或迁移的工作,可能需要同时使用MySQL和ClickHouse,所以需要了解两者的异同。 首先,我应该明确回答用户的问题,指出两者有相似之处,但也有显著的同。用户可能希望利用已有的MySQL知识来快速上手ClickHouse,但需要注意差异以避免错误。 接下来,我需要比较两者的基本语法,比如SELECT、INSERT这些常见操作是否类似。例如,ClickHouse支持类似的SELECT语句,但可能在函数或特性上有扩展。同时,ClickHouse的INSERT INTO VALUES语法相似,但更推荐使用批量插入,这可能和MySQL的优化有关。 然后,数据类型方面,ClickHouse有更多针对分析优化的类型,比如Nullable和LowCardinality,而MySQL更通用。用户可能需要了解这些类型的使用场景,比如Nullable处理空值,LowCardinality优化存储。 函数部分,虽然都有聚合函数,但ClickHouse的更为丰富,比如quantileExact,这对数据分析很有用。用户如果做数据分析,会需要这些函数,而普通CRUD可能用上。 高级特性方面,ClickHouse的引擎和物化视图是重点,比如MergeTree引擎的同变体,用户需要根据场景选择合适的引擎。物化视图在ClickHouse中自动更新,而MySQL需要手动处理,这可能影响数据管道的设计。 性能优化方面,ClickHouse的分布式架构和向量化查询处理是其优势,但用户需要注意数据分片和索引的使用,这和MySQL的索引策略同。比如,ClickHouse的索引是B树,而是稀疏索引,适合大数据范围查询。 用户可能的深层需求是评估是否迁移到ClickHouse,或者整合两者使用。比如,用MySQL处理事务,用ClickHouse做分析。这时候需要强调ClickHouse的OLAP优势,以及语法上的兼容性和差异,帮助用户平滑过渡。 另外,用户可能遇到的误区是认为语法相同就完全兼容,但实际上细节上的差异可能导致错误。比如,ClickHouse对JOIN的处理同,或者在事务支持上的缺失,需要明确指出这些以避免问题。 最后,应该给出建议,比如使用MySQL语法兼容模式,或者注意特定的方言差异。同时,推荐用户查阅官方文档,特别是当使用特定功能时,确保正确性和性能优化。</think>ClickHouse 的语法与 MySQL **有相似之处,但存在显著差异**。虽然两者都属于 SQL 类语言,且 ClickHouse 在设计时部分兼容 MySQL 语法(以降低学习成本),但由于 ClickHouse 专注于 **OLAP 联机分析场景**,而 MySQL 是典型的 **OLTP 联机事务处理数据库**,因此它们在语法、函数、优化策略等方面有本质区别。以下是关键对比: --- ### **1. 基础语法相似性** - **SELECT / INSERT / UPDATE / DELETE** 基础语法结构类似,例如: ```sql -- ClickHouse 和 MySQL 均支持的 SELECT 写法 SELECT column1, COUNT(*) FROM table WHERE condition GROUP BY column1; ``` - **JOIN 操作** 支持 `INNER JOIN`、`LEFT JOIN` 等,但 ClickHouse 对 JOIN 的性能优化策略与 MySQL 同(如分布式 JOIN 需要额外配置)。 --- ### **2. 显著差异点** #### **2.1 数据类型** | **ClickHouse** | **MySQL** | 说明 | |--------------------------|---------------------|-------------------------------------| | `Nullable(T)` | `NULL` 修饰符 | ClickHouse 显式定义字段是否可为空 | | `LowCardinality(String)`| 无 | 优化低基数字符列的存储和查询性能 | | `Array(T)` | JSON 类型 | ClickHouse 原生支持数组类型 | | `AggregateFunction` | 无 | ClickHouse 特有的预聚合类型(如 Sum、Count) | #### **2.2 函数与特性** | **功能** | **ClickHouse** | **MySQL** | |-------------------------|-----------------------------------------|------------------------------------| | **字符串函数** | `lengthUTF8(str)` 计算 UTF-8 字符长度 | `CHAR_LENGTH(str)` | | **日期函数** | `toYYYYMMDDhhmmss()` 精确到秒的格式化 | `DATE_FORMAT(date, '%Y%m%d%H%i%s')`| | **聚合函数** | 支持 `quantileExact(0.9)(column)` 等统计函数 | 仅基础聚合(如 `AVG`, `SUM`) | | **分页查询** | `LIMIT n BY column` 按列分组后分页 | 仅支持 `LIMIT offset, size` | | **分布式查询** | 原生支持分布式(如 `cluster()` 语法) | 需中间件或手动分片 | #### **2.3 高级特性** | **特性** | **ClickHouse** | **MySQL** | |-------------------------|-----------------------------------------|------------------------------------| | **引擎** | 必须指定引擎(如 `MergeTree`、`Kafka`) | 默认 InnoDB/MyISAM,无需显式声明 | | **物化视图** | 自动更新,支持持久化存储 | 需手动刷新,基于基计算 | | **索引** | 稀疏索引(适合范围查询) | B+ 树索引(适合点查) | | **事务支持** | 支持 ACID 事务 | 支持完整事务(InnoDB) | --- ### **3. 示例对比** #### **3.1 建语句** ```sql -- ClickHouse(需指定引擎和分区键) CREATE TABLE logs ( timestamp DateTime, user_id Int32, event String ) ENGINE = MergeTree() ORDER BY (timestamp, user_id); -- MySQL(默认引擎为 InnoDB) CREATE TABLE logs ( timestamp DATETIME, user_id INT, event VARCHAR(255) ); ``` #### **3.2 插入数据** ```sql -- ClickHouse(推荐批量插入) INSERT INTO logs VALUES ('2023-10-01 12:00:00', 1, 'login'), ('2023-10-01 12:01:00', 2, 'logout'); -- MySQL(单条插入更常见) INSERT INTO logs (timestamp, user_id, event) VALUES ('2023-10-01 12:00:00', 1, 'login'); ``` --- ### **4. 性能优化差异** | **场景** | **ClickHouse** | **MySQL** | |------------------------|-----------------------------------------|------------------------------------| | **大数据量查询** | 向量化执行引擎,并行处理 PB 级数据 | 单线程执行,适合 TB 级以下数据 | | **高并发写入** | 支持批量写入(每秒百万级) | 适合低延迟事务写入(每秒数千级) | | **复杂分析查询** | 预聚合、近似计算优化(如 `approxCountDistinct`) | 依赖索引和内存优化,性能有限 | --- ### **5. 使用建议** 1. **语法兼容模式**: ClickHouse 支持 `SET dialect = 'mysql'`,可部分兼容 MySQL 语法(如函数别名),但需谨慎使用。 2. **避免直接迁移**: 若从 MySQL 迁移到 ClickHouse,需重写复杂查询(如事务逻辑、高频 UPDATE/DELETE)。 3. **适用场景**: - **ClickHouse**:日志分析、时序数据、实时报等 OLAP 场景。 - **MySQL**:事务处理、高频更新、强一致性要求的 OLTP 场景。 --- ### **6. 总结** - **相似性**:基础 SQL 语法兼容,适合简单查询迁移。 - **差异性**:数据类型、函数、高级特性(如引擎、索引)需特别注意。 - **核心原则**:根据业务场景选择工具——**OLTP 用 MySQL,OLAP 用 ClickHouse**。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值