MySQL优化索引及优化汉字模糊查询语句

本文介绍了如何通过优化MySQL查询语句来提升索引的使用效率,特别是针对like语句的优化,包括对英文和中文字符的处理方法。
 

利用mysql这种关系型数据库来做索引,的确有些勉强了,也只能看情况来说了,有些简单的功能还是可以考虑的。

对于模糊查询语句,最不利的情况是要like '%key%'这样的查询,但是如果是like 'key%'这种情况,那么mysql的索引在些查询方式上还是可以优化的。

网上常见的是ASCII的英文字符优化,如下:

select corp_code, corp_corp from tb_Z_Corp where corp_code like '0008%';

举个例子来看看问题的来源吧:

先看一下要试验表的创建语句和结构,这是一个只包含股票代码和股票名称的数据表,主键为股票代码:

mysql> show create table tb_Z_Corp;
+-----------+-----------------------------------+
| Table     | Create Table                      |
+-----------+-----------------------------------+
| tb_Z_Corp | CREATE TABLE `tb_Z_Corp` (
  `corp_code` char(10) NOT NULL,
  `corp_corp` varchar(60) NOT NULL,
  PRIMARY KEY  (`corp_code`),
  KEY `idx_Z_Corp_corp_corp` (`corp_corp`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8            | 
+-----------+-----------------------------------+

mysql> desc tb_Z_Corp;
+---------------+-------------+------+-----+---------+-------+
| Field         | Type        | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+-------+
| corp_code     | char(10)    | NO   | PRI |         |       | 
| corp_corp     | varchar(60) | NO   | MUL |         |       | 
+---------------+-------------+------+-----+---------+-------+

表里面的数据举例如下(股票代码和股票名称):

+-----------+--------------+
| corp_code | corp_corp    |
+-----------+--------------+
| 000800    | 一汽轿车     | 
| 000801    | 四川九洲     | 
| 000802    | 北京旅游     | 
| 000803    | 金宇车城     | 
| 000805    | *ST炎黄      | 
| 000806    | 银河科技     | 
| 000807    | 云铝股份     | 
| 000809    | 中汇医药     | 

看一下要待优化的语句(一个英文、一个中文的):

select corp_code, corp_corp from tb_Z_Corp where corp_code like '0008%';
select corp_code, corp_corp from tb_Z_Corp where corp_corp like '江%';

对于第一个待优化的SQL语句来说,比较简单,很地方都介绍过怎样优化:

select corp_code, corp_corp from tb_Z_Corp where corp_code >= '0008' and corp_code < '0009';

而对于第二个是中文字符,马上想到是加一个最大编码的汉字,这里数据库存储的是UTF-8格式存储,而汉字的编码为3字节,所以按其最大编码的规则应该是:
Unicode编码是从U+0800到U+FFFF先标记一下这16位:“zzzzyyyy yyxxxxxx”;
然后把这16位对应到UTF-8的编码:“1110zzzz 10yyyyyy 10xxxxxx”。
所以最大的3个字节的编码为“11101111 10111111 10111111”,也就是十六进制的“EFBFBF”。
在MySQL中,用x'EFBFBF'表明这里面是用16进制编码的字符串,所以我们优化后的语句应该是这样的:

select corp_code, corp_corp from tb_Z_Corp where corp_corp >= '江' and corp_corp < CONCAT('江', x'EFBFBF');

这样就达到了不用like语句比较表中的每一条记录,而直接使用索引快速检索。看,结果出来了:

+-----------+--------------+
| corp_code | corp_corp    |
+-----------+--------------+
| 600750    | 江中药业     | 
| 002226    | 江南化工     | 
| 601199    | 江南水务     | 
| 000519    | 江南红箭     | 
| 600527    | 江南高纤     | 
| 002061    | 江山化工     | 
| 600389    | 江山股份     | 
| 600212    | 江泉实业     | 
| 002484    | 江海股份     | 
| 000816    | 江淮动力     | 
| 600418    | 江淮汽车     | 
| 002176    | 江特电机     | 
<think>首先,用户的问题是:“我想查找MySQL中模糊查询语句的相关信息 请问MySQL模糊查询语句”。所以,我需要提供关于MySQL模糊查询语句的详细信息。 用户提供了几条引用,我需要参考这些引用: - 引用[1]:提到了MySQL模糊查询的几种方法,包括like、REGEXP、LOCATE、POSITION、INSTR、FIND_IN_SET。 - 引用[2]:讨论了not in的使用,并提到模糊查询like。 - 引用[3]:解释了通配符模糊查询,包括%和_,以及like操作符。 - 引用[4]:讨论了模糊查询的注意事项,如大小写敏感、尾部空格处理NULL值。 - 引用[5]:是关于基本查询语句的,比如=、>、<等,但用户提到模糊查询,所以这可能相关但不直接。 我的回答需要基于这些引用,尽可能多地参考它们。用户说:“上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题和你的回答。” 查看历史,用户上一次的问题是我的第一条消息,是关于系统指令的示例,没有具体内容。所以在上下文中,用户没有之前的互动;这是我的第一个响应。因此,我应该专注于当前问题和提供的引用。 回答结构:指令要求回答结构清晰,帮助用户逐步解决问题。所以,我需要组织信息清晰。 关键元素: - 模糊查询的定义:模糊查询用于匹配部分字符串,而不是精确匹配。 - 方法:基于引用[1],有几种方法:like、REGEXP、LOCATE、POSITION、INSTR、FIND_IN_SET。 - 细节: - LIKE:使用%和_通配符。%匹配零个或多个字符,_匹配单个字符。 - REGEXP:使用正则表达式。 - LOCATE、POSITION、INSTR、FIND_IN_SET:基于位置的函数。 - 注意事项:从引用[4],注意大小写敏感(取决于MySQL配置)、尾部空格("%test"不匹配"test ")、NULL值(%不匹配NULL)。 - 示例:提供一些SQL示例来展示如何使用这些方法。 指令还要求生成相关问题。在回答末尾添加相关问题。 格式要求: - 行内数学表达式用$...$,但这里没有数学内容,所以可能不需要。 - 独立公式用$$...$$,同样可能不需要。 - LaTeX语法正确:如果使用数学符号,确保正确,但这里主要是文本。 - 使用中文回答:整个回答用中文。 - 引用的段落末尾自然地添加引用标识:例如,[^1]。所以,当引用特定信息时,添加引用源。 组织回答: 1. **介绍模糊查询**:简要解释什么是模糊查询及其在MySQL中的应用。 2. **主要方法**:详细描述每种模糊查询方法,给出语法和示例。 - 基于引用[1]:列出方法。 - 提供示例SQL语句。 3. **通配符详解**:基于引用[3],解释%和_。 4. **注意事项**:基于引用[4],讨论大小写、空格、NULL等。 5. **总结**:简要总结最佳实践或常见用法。 生成相关问题:在末尾添加几个相关问题。 确保回答真实可靠:基于标准MySQL知识,参考提供的引用。 大纲: - 开头:直接回答用户查询。 - 主体: - 模糊查询方法: - LIKE操作符 - REGEXP操作符 - 函数:LOCATE, POSITION, INSTR, FIND_IN_SET - 每个方法的说明和示例。 - 注意事项。 - 总结。 相关问题: 1. 如何在MySQL处理大小写敏感的模糊查询? 2. 模糊查询的性能优化技巧? 3. 何时使用LIKE vs REGEXP? 添加引用标识:例如,当提到引用[1]的信息时,添加[^1]。 现在,起草回答。 </think>### MySQL模糊查询语句详解 在MySQL中,模糊查询用于匹配部分字符串,而不是精确值,常用于搜索功能(如用户名、产品名等)。基于您提供的引用,MySQL支持多种模糊查询方法,包括使用通配符、正则表达式和内置函数。下面我将逐步解释这些方法,确保回答结构清晰,并基于引用内容(如[^1], [^2], [^3], [^4])提供可靠信息。 #### 1. **LIKE操作符(常用通配符模糊查询)** LIKE是最基础的模糊查询方法,使用通配符`%`和`_`来匹配字符串: - `%`:匹配零个或多个任意字符(包括空字符串)。 - `_`:匹配单个任意字符(必须有一个字符)。 基本语法: ```sql SELECT * FROM 表名 WHERE 列名 LIKE '模式'; ``` 示例: - 查找以"test"开头的记录:`SELECT * FROM users WHERE name LIKE 'test%';`(匹配"test123"或"test",但不匹配"123test"[^3])。 - 查找第二个字符为"a"的记录:`SELECT * FROM products WHERE name LIKE '_a%';`(匹配"apple"或"banana",但不匹配"grape"[^3])。 注意事项: - **大小写敏感**:MySQL默认不区分大小写(取决于服务器配置),例如`LIKE 'test%'`可能匹配"Test"或"TEST",但如果配置为区分大小写,则不会匹配[^4]。 - **尾部空格**:如`'%test'`不会匹配"test "(尾部有空格的字符串),需处理空格或用TRIM函数[^4]。 - **NULL值**:`LIKE '%'`不会匹配NULL值的记录,需额外检查:`SELECT * FROM table WHERE column IS NULL OR column LIKE '%';`[^4]。 这种方法简单易用,但不适合复杂匹配(如多条件组合)。 #### 2. **REGEXP操作符(正则表达式模糊查询)** 当需要更灵活的匹配时,REGEXP支持正则表达式,功能更强大: - 语法:`SELECT * FROM 表名 WHERE 列名 REGEXP '正则模式';` 示例: - 匹配邮箱格式:`SELECT * FROM contacts WHERE email REGEXP '^[a-z]+@[a-z]+\.[a-z]{2,3}$';`(匹配"user@example.com")。 - 查找包含"test"或"demo"的记录:`SELECT * FROM logs WHERE message REGEXP 'test|demo';`[^1]。 优点:支持模式如`|`(或)、`^`(开头)、`$`(结尾)。但需注意性能,正则查询可能比LIKE慢[^1]。 #### 3. **内置函数模糊查询** 基于引用[^1],MySQL还提供特定函数实现模糊匹配,适合位置相关查询: - **LOCATE('substr', str, pos)**:返回子串出现的位置(从pos开始)。示例:查找"substr"在字符串中的位置,`SELECT LOCATE('test', name, 1) AS pos FROM employees WHERE pos > 0;`(返回位置索引)。 - **POSITION('substr' IN `字段`)**:等同于LOCATE,语法更简洁。示例:`SELECT * FROM books WHERE POSITION('book' IN title) > 0;`(匹配包含"book"的标题)。 - **INSTR(`str`, 'substr')**:类似于LOCATE,返回子串位置。示例:`SELECT * FROM orders WHERE INSTR(description, 'urgent') > 0;`。 - **FIND_IN_SET(str1, str2)**:在逗号分隔列表中查找str1。示例:`SELECT * FROM users WHERE FIND_IN_SET('admin', roles) > 0;`(匹配roles字段为"admin,user"的记录)。 这些函数适合特定场景,如精确位置匹配或列表查询。 #### 4. **模糊查询注意事项总结** 基于引用[^3]和[^4],使用模糊查询时需注意: - **性能影响**:模糊查询(如`LIKE '%test'`)通常无法使用索引,可能导致全表扫描,建议在查询字段上创建索引优化模式。 - **反义查询**:结合NOT操作符,例如`NOT LIKE`或`NOT IN`(如引用[^2]所示),避免不必要的记录:`SELECT * FROM EMP WHERE SAL NOT IN (800, 5000);`。 - **与其他操作符结合**:模糊查询可与比较操作符(如`=`, `>`, `<`[^5])一起使用,实现复杂过滤。 - **最佳实践**:优先使用LIKE简单匹配,复杂需求用REGEXP;测试大小写和空格行为以确保准确性。 #### 总结 MySQL模糊查询主要通过LIKE(通配符)、REGEXP(正则)和内置函数(如LOCATE)实现。选择方法取决于需求:LIKE适合简单模糊匹配,REGEXP适合高级模式,函数适用于位置敏感查询。实际使用时,注意性能优化和边界情况(如大小写、空格)。如果您有具体查询场景(如搜索用户表),我可以提供更针对性的示例。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值