数据库调优教程(十) 【精华章节】解决like ’%str’ 时索引不被使用的4种方法

本文详细介绍了如何解决MySQL中使用LIKE '%str%'导致索引失效的问题,提供了包括选择主键查询、应用覆盖索引、使用全文索引以及利用全文检索引擎工具在内的四种解决方案,对于大数据量表的高效模糊查询具有指导意义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

三、           索引


7.      解决like’%str’不使用模糊查询的4种方法


上一讲最后说了,只要模糊查询的模糊值在字符串前面,则不会使用索引,‘%aaa’和‘_aaa’都不会!

如下


应该说这是Mysql给程序员们开的一个玩笑。要是我的表数据量很大,而且又需要使用like’%%’这样的模糊查询来检索时,该怎么办??

接下来,笔者将会给大家分享解决这个问题的四种方法


1)    Select主键

只要Select的字段刚好是主键,那么就会使用到索引(只对innodb数据库有效)

比如下面的

<think>好的,用户问的是从MySQL切换到DM达梦数据库需要注意哪些地方。我需要先了解这两个数据库的区别,以及迁移过程中可能遇到的问题。首先,达梦作为国产数据库,可能在语法、功能、性能化等方面与MySQL存在差异。用户可能是企业的开发人员或者系统架构师,负责数据库迁移工作,他们需要具体的迁移步骤和注意事项,避免踩坑。 用户可能已经有一定的MySQL使用经验,但对达梦太熟悉,需要了解迁移的具体挑战,比如SQL语法差异、事务处理、存储引擎、备份恢复等。还可能关心数据迁移工具的选择、性能、兼容性问题以及运维方面的变化。此外,用户可能没有明确提到的潜在需求包括合规性、安全性、成本评估以及后续维护的支持情况。 接下来需要分点整理注意事项,比如语法兼容性、数据类型差异、事务和锁机制、迁移工具使用、性能化、系统函数变化、权限管理、备份策略、测试验证等。每个点都需要具体说明MySQL和达梦的同之处,以及迁移如何整。例如,达梦的存储过程语法可能与MySQL同,需要重写;索引机制可能有差异,需要化查询语句。 还要考虑数据迁移过程中的步骤,比如使用DTS工具还是自行开发脚本,数据校验的方法,迁移后的测试策略,包括功能测试和性能测试。另外,应用层的适配也很重要,比如连接池配置、ORM框架的支持情况,可能需要修改连接字符串或驱动类。 最后需要提醒用户进行充分的测试和备份,确保迁移后的系统稳定运行。可能还需要建议分阶段迁移,先在测试环境验证,再逐步切换到生产环境,减少风险。</think>将MySQL迁移到达梦数据库,需重点关注以下技术差异与适配要点(附典型问题解决方案): --- ### 一、SQL语法差异适配 1. **分页机制** - MySQL:`LIMIT 10 OFFSET 20` - 达梦:`SELECT TOP 10 * FROM (SELECT ROWNUM rn,t.* FROM table t WHERE ROWNUM<=30) WHERE rn>20` - 改造方案:建立分页函数映射层,实现语法自动转换 2. **字符串处理** - MySQL:`CONCAT(str1,str2)`支持NULL值拼接 - 达梦:`str1 || str2`遇到NULL返回NULL,需显式使用`NVL(str1,'')`处理 - 示例转换: ```sql -- 原MySQL SELECT CONCAT(address, tel) FROM users -- 达梦适配 SELECT NVL(address,'') || NVL(tel,'') FROM users ``` 3. **日期函数** - MySQL:`DATE_FORMAT(NOW(),'%Y-%m')` - 达梦:`TO_CHAR(SYSDATE, 'yyyy-mm')` - 需批量替换56种日期格式表达式 --- ### 二、数据类型映射 | MySQL类型 | 达梦类型 | 注意要点 | |----------------|----------------|----------------------------------| | TINYINT(1) | BOOLEAN | Java中需处理为Boolean类型 | | DATETIME(6) | DATETIME(6) | 达梦默认精度为0,需显式指定 | | JSON | VARCHAR(4000) | 需应用层实现JSON解析 | | AUTO_INCREMENT | IDENTITY(1,1) | 达梦支持复合主键自增 | > **特殊案例**:MySQL的`ENUM('A','B')`需转换为达梦的`VARCHAR(10) CHECK ...` --- ### 三、事务与锁机制 1. **隔离级别差异** - 达梦默认`READ COMMITTED`,但通过`SET TRANSACTION ISOLATION LEVEL`设置后,实际行为与MySQL存在差异: - 幻读处理:达梦在RR级别下通过`SELECT ... FOR UPDATE`实现全表间隙锁 2. **死锁检测** - MySQL:等待超后自动回滚 - 达梦:需配置`DEADLOCK_CHECK_INTERVAL=5`(秒级检测间隔) --- ### 四、迁移实施步骤 1. **结构迁移** ```bash # 使用达梦DTS工具转换 ./dts -s mysql://user:pwd@host:3306/db \ -t dm://user:pwd@host:5236/db \ --type=struct ``` 2. **数据迁移** - 分片策略:按`MOD(id,10)`将大表拆分为10个并行任务 - 数据校验: ```sql -- MySQL校验SQL SELECT COUNT(*) AS cnt, MD5(GROUP_CONCAT(id ORDER BY id)) FROM table -- 达梦校验(需处理CLOB类型): SELECT COUNT(*), DBMS_LOB.SUBSTR(SYS_CONNECT_BY_PATH(id,','), 4000) FROM (SELECT id, ROWNUM rn FROM table ORDER BY id) ``` 3. **存储过程迁移** ```sql -- MySQL存储过程 DELIMITER $$ CREATE PROCEDURE test(IN p INT) BEGIN DECLARE v INT DEFAULT 0; SET v = p + 1; SELECT v; END$$ -- 达梦适配版 CREATE OR REPLACE PROCEDURE test(p IN INT) AS v INT := 0; BEGIN v := p + 1; PRINT v; END; ``` --- ### 五、性能要点 1. **索引策略整** - 达梦的位图索引在低基数列(如性别)上效率提升显著: ```sql CREATE BITMAP INDEX idx_gender ON users(gender); ``` 2. **执行计划差异** - 达梦对`WHERE col LIKE '%value%'`无法使用索引,需改造为全文索引: ```sql CREATE CONTEXT INDEX idx_content ON docs(content) LEXER DEFAULT_LEXER; ``` 3. **内存配置** ```ini # 达梦dm.ini关键参数 MEMORY_POOL = 2000 # 共享内存池(MB) BUFFER_POOL_SIZE = 100000 # 数据缓冲区(page数) ``` --- ### 六、运维监控变化 1. **慢查询分析** - 达梦需开启`SVR_LOG.SQL_TRACE_MASK=31`记录完整日志 - 使用`DM_MONITOR`视图: ```sql SELECT sess_id, sql_text, time_used FROM V$LONG_EXEC_SQLS WHERE time_used > 5000; -- 5秒以上查询 ``` 2. **备份策略** ```bash # 达梦联机备份 ./disql SYSDBA/SYSDBA@localhost:5236 BACKUP DATABASE FULL TO 'BAK_FULL' BACKUPSET '/dmbak/full'; ``` --- ### 七、典型错误案例 1. **隐式类型转换** - MySQL允许`SELECT * FROM table WHERE date_col = '2023-02-30'`(自动转为NULL) - 达梦会直接报错:"日期格式非法" 2. **子查询限制** - 达梦要求关联子查询必须包含`ROWNUM`: ```sql -- 错误写法 SELECT * FROM t1 WHERE id IN (SELECT id FROM t2) -- 正确适配 SELECT * FROM t1 WHERE id IN (SELECT id FROM (SELECT id FROM t2) tmp) ``` --- 迁移完成后建议执行: 1. 压力测试:使用TPC-C工具验证事务处理能力 2. 回归测试:覆盖所有业务SQL语句 3. 建立兼容层:对差异函数进行统一封装 建议在过渡期保留MySQL双写机制,通过数据比对工具(如自研`DeltaChecker`)确保数据一致性,待验证稳定后再完全切换。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值