服务端指南 数据存储篇 | MySQL(03) 如何设计索引
改善性能最好的方式,就是通过数据库中合理地使用索引,换句话说,索引是提高 MySQL 数据库查询性能的主要手段。在下面的章节中,介绍了索引类型、强制索引、全文索引。
原文地址:服务端指南 数据存储篇 | MySQL(03) 如何设计索引
博客地址:blog.720ui.com/
基本索引类型
MySQL 索引可以分为单列索引、复合索引、唯一索引、主键索引等。这里,将为读者介绍这几种索引的特点。
单列索引
单列索引:单列索引是最基本的索引,它没有任何限制。
创建一个单列索引,例如:
create index index_name on tbl_name(index_col_name);复制代码
同时,也可以通过修改表结构的方式添加索引,例如:
alter table tbl_name add index index_name on (index_col_name);复制代码
复合索引
复合索引:复合索引是在多个字段上创建的索引。复合索引遵守“最左前缀”原则,即在查询条件中使用了复合索引的第一个字段,索引才会被使用。因此,在复合索引中索引列的顺序至关重要。
创建一个复合索引,例如:
create index index_name on tbl_name(index_col_name,...);复制代码
同时,也可以通过修改表结构的方式添加索引,例如:
alter table tbl_name add index index_name on (index_col_name,...);复制代码
唯一索引
唯一索引:唯一索引和单列索引类似,主要的区别在于,唯一索引限制列的值必须唯一,但允许有空值。对于多个字段,唯一索引规定列值的组合必须唯一。
创建一个复合索引,例如:
create unique index index_name on tbl_name(index_col_name,...);复制代码
同时,也可以通过修改表结构的方式添加索引,例如:
alter table tbl_name add unique index index_name on (index_col_name,...);复制代码
主键索引
主键索引:主键索引是一种特殊的唯一索引,不允许有空值。此外, CREATE INDEX 不能创建主键索引,需要使用 ALTER TABLE 代替,例如:
alter table tbl_name add primary key(index_col_name);复制代码
强制索引
有时,因为使用 MySQL 的优化器机制,原本应该使用索引的优化器,反而选择执行全表扫描或者执行的不是预期的索引。此时,可以通过强制索引的方式引导优化器采取正确的执行计划。
使用强制索引,SQL 语句只使用建立在 index_col_name 上的索引,而不使用其它的索引。
select * from tbl_name force index (index_col_name) …复制代码
切记,不要滥用强制索引,因为 MySQL 的优化器会同时评估 I/O 和 CPU 的成本,一般情况下,可以自动分析选择最合适的索引。
如果优化器成本评估错误,因而没有选择最佳方案,最好的方法应该是将合适的索引修改得更好。
如果某个 SQL 语句使用强制索引,需要在系统迭代开发过程中时时维护强制索引,一方面,需要保证使用的强制索引最优,另外一面,需要保证所使用的强制索引不能被误删,不然将导致 SQL 报错。
因此,如果某个 SQL 语句必须要使用强制索引,建议在团队内部开展严格地评审后才可以使用。
全文索引
在一般情况下,模糊查询都是通过 like 的方式进行查询。但是,对于海量数据,这并不是一个好办法,在 like "value%" 可以使用索引,但是对于 like "%value%" 这样的方式,执行全表查询,这在数据量小的表,不存在性能问题,但是对于海量数据,全表扫描是非常可怕的事情,所以 like 进行模糊匹配性能很差。
这种情况下,需要考虑使用全文搜索的方式进行优化。全文搜索在 MySQL 中是一个 FULLTEXT 类型索引。 FULLTEXT 索引在 MySQL 5.6 版本之后支持 InnoDB,而之前的版本只支持 MyISAM 表。
假设,有一张应用全文索引表。
CREATE TABLE IF NOT EXISTS `app_full_text` (`app_id` bigint(20) NOT NULL,`app_name_full_text` text NOT NULL,`introduce_full_text` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;复制代码
现在需要对应用的名称创建全文索引,可以这么设计。
alter table `app_full_text` add fulltext key `app_name_intro` (`app_name_full_text`);复制代码
默认 MySQL 不支持中文全文检索,对此,网上的方案很多,例如添加 MySQL 扩展,或者将内容转换成拼音的方式存储在索引表,或者使用 IKAnalyzer 分词库等,其效果都不是非常的理想。使用拼音分词,虽然可以查询到内容,但是如果拼音相同的情况,是非常致命的,而且分词的粒度也是个很可怕的问题。使用 IKAnalyzer 分词库,效果也不是很好。因为业务的需要,命中率也是非常重要的,有的关键字没有进行分词导致查询不到的问题。
我之前的临时解决方案。如下:
- 为中文内容表提供一个全文索引表,存储全文索引分词信息,两张表根据中文内容表的 ID 进行关联。
- 将内容进行分词后,用 base64 编码,保存在全文索引表中。
- 关键的一步,如何分词,分词的命中率问题。很简单,自定义分词库,写一个分词算法将所有的组合进行分词,在内容不多的情况下非常有用。举个例子,“梁桂钊”,可以进行自定义分词:[梁、桂、钊、梁桂、桂钊、梁桂钊]。
事实上,MySQL 全文搜索只是一个临时方案,对于全文搜索场景,更专业的做法是使用全文搜索引擎,例如 ElasticSearch 或 Solr。
(完)
更多精彩文章,尽在「服务端思维」微信公众号!
服务端指南 数据存储篇 | MySQL(03) 如何设计索引相关推荐
- 服务端指南 数据存储篇 | 选择合适的数据存储方案
在服务端会经常遇到数据存储的选型问题,是选择使用关系型数据库 MySQL,还是选择内存数据库 Redis,还是选择文档数据库 MongoDB,还是选择列族数据库 HBase, 还是选择全文搜索引擎 E ...
- 服务端指南 数据存储篇 | 聊聊 Redis 使用场景(转)
作者:梁桂钊 本文,是升级版,补充部分实战案例.梳理几个场景下利用 Redis 的特性可以大大提高效率. 随着数据量的增长,MySQL 已经满足不了大型互联网类应用的需求.因此,Redis 基于内存存 ...
- 用户画像 | 标签数据存储之MySQL真实应用
本文已收录github:https://github.com/BigDataScholar/TheKingOfBigData,里面有大数据高频考点,Java一线大厂面试题资源,上百本免费电子书籍,作者 ...
- 网络游戏《丛林战争》开发与学习之(二):粘包分包现象以及服务端解析数据
本篇博客主要介绍数据发送和接收时遇到的粘包和分包现象,以及实现服务端解析收到消息的代码,本节的代码是在第(一)部分的基础上进行的,可以先浏览下第一部分https://blog.csdn.net/s13 ...
- 用户画像标签数据存储之MySQL存储
目录 0. 相关文章链接 1. 元数据管理 2. 监控预警数据 2.1. 标签计算数据监控 2.2. 服务层同步数据监控 2.3. 结果集存储 注:此博文为根据 赵宏田 老师的 用户画像·方法论与工程 ...
- mysql数据存储方式_数据存储在mysql的两种方式
数据存储在mysql的两种方式 发布时间:2020-05-12 16:16:25 来源:亿速云 阅读:250 作者:三月 下文主要给大家带来数据存储在mysql的两种方式,希望这些内容能够带给大家实际 ...
- java Socket Tcp示例三则(服务端处理数据、上传文件)
示例一: package cn.itcast.net.p5.tcptest; import java.io.BufferedReader; import java.io.IOException; im ...
- Spring Boot干货系列:数据存储篇-SQL关系型数据库之MyBatis的使用
Spring Boot干货系列:数据存储篇-SQL关系型数据库之MyBatis的使用 前言 上篇我们介绍了Spring Boot对传统JdbcTemplate的集成,这次换一下,介绍下Spring B ...
- 服务端指南 | 良好的 API 设计指南
设计一套良好的 API 接口. 原文地址:服务端指南 | 良好的 API 设计指南 博客地址:blog.720ui.com/ 版本号 在 RESTful API 中,API 接口应该尽量兼容之前的版本 ...
最新文章
- Linux学习(2)-命令基础背景+命令使用帮助获取
- 蓝书4.1-4.4 树状数组、RMQ问题、线段树、倍增求LCA
- show status 优化mysql_mysql优化--show status
- android分享的主标题,Android 自定义标题栏(title栏)
- 【IT资讯】阿里新推出“阿里云网盘” 速度10MBs,百度网盘或迎来最强对手!
- 思考题目,仔细检查,外加一个ceil函数
- 正则表达式注意事项以及常用方法
- Java TheadLocal
- 前端学习(1504):组件通信的几种情况
- TurnipBit开发板DIY呼吸的吃豆人教程实例
- python中StringIO和BytesIO
- 编码器z相 C语言代码,编码器的Z相是什么?
- Abaqus相关报错合集
- ARP报文头部格式和请求流程
- 学生表mysql查询语句
- linux shrink dev sd,Virt相关命令(转)
- 万年历(C语言代码实现)
- linux查看主板最大内存容量,Linux 查看内存插槽数、最大容量的方法
- C++程序设计课程同步项目——循环结构程序设计项目任务一
- motoxt 1085 android8,Moto(Moto)X XT1085/全网通手机系统介绍评测-ZOL中关村在线
热门文章
- (ICASSP 19)AUTOMATIC GRAMMAR AUGMENTATION FOR ROBUST VOICE COMMAND RECOGNITION
- 『Others』一键关闭所有应用程序
- 华为MateBook D14 安装ubuntu16 wifi、蓝牙、触控板驱动问题解决
- 思科交换机命令大全(二)
- 一个免费的FLV编码工具(以及免费的FLV播放器)
- 中国高校鄙视链指南!
- 计算机网络(2)——标准化工作及相关组织
- 康耐视 visionpro图像角度识别
- BABvsBABAB
- python双星号是什么意思_Python字典前双星号(**)的作用