改善性能最好的方式,就是通过数据库中合理地使用索引,换句话说,索引是提高 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) 如何设计索引相关推荐

  1. 服务端指南 数据存储篇 | 选择合适的数据存储方案

    在服务端会经常遇到数据存储的选型问题,是选择使用关系型数据库 MySQL,还是选择内存数据库 Redis,还是选择文档数据库 MongoDB,还是选择列族数据库 HBase, 还是选择全文搜索引擎 E ...

  2. 服务端指南 数据存储篇 | 聊聊 Redis 使用场景(转)

    作者:梁桂钊 本文,是升级版,补充部分实战案例.梳理几个场景下利用 Redis 的特性可以大大提高效率. 随着数据量的增长,MySQL 已经满足不了大型互联网类应用的需求.因此,Redis 基于内存存 ...

  3. 用户画像 | 标签数据存储之MySQL真实应用

    本文已收录github:https://github.com/BigDataScholar/TheKingOfBigData,里面有大数据高频考点,Java一线大厂面试题资源,上百本免费电子书籍,作者 ...

  4. 网络游戏《丛林战争》开发与学习之(二):粘包分包现象以及服务端解析数据

    本篇博客主要介绍数据发送和接收时遇到的粘包和分包现象,以及实现服务端解析收到消息的代码,本节的代码是在第(一)部分的基础上进行的,可以先浏览下第一部分https://blog.csdn.net/s13 ...

  5. 用户画像标签数据存储之MySQL存储

    目录 0. 相关文章链接 1. 元数据管理 2. 监控预警数据 2.1. 标签计算数据监控 2.2. 服务层同步数据监控 2.3. 结果集存储 注:此博文为根据 赵宏田 老师的 用户画像·方法论与工程 ...

  6. mysql数据存储方式_数据存储在mysql的两种方式

    数据存储在mysql的两种方式 发布时间:2020-05-12 16:16:25 来源:亿速云 阅读:250 作者:三月 下文主要给大家带来数据存储在mysql的两种方式,希望这些内容能够带给大家实际 ...

  7. java Socket Tcp示例三则(服务端处理数据、上传文件)

    示例一: package cn.itcast.net.p5.tcptest; import java.io.BufferedReader; import java.io.IOException; im ...

  8. Spring Boot干货系列:数据存储篇-SQL关系型数据库之MyBatis的使用

    Spring Boot干货系列:数据存储篇-SQL关系型数据库之MyBatis的使用 前言 上篇我们介绍了Spring Boot对传统JdbcTemplate的集成,这次换一下,介绍下Spring B ...

  9. 服务端指南 | 良好的 API 设计指南

    设计一套良好的 API 接口. 原文地址:服务端指南 | 良好的 API 设计指南 博客地址:blog.720ui.com/ 版本号 在 RESTful API 中,API 接口应该尽量兼容之前的版本 ...

最新文章

  1. Linux学习(2)-命令基础背景+命令使用帮助获取
  2. 蓝书4.1-4.4 树状数组、RMQ问题、线段树、倍增求LCA
  3. show status 优化mysql_mysql优化--show status
  4. android分享的主标题,Android 自定义标题栏(title栏)
  5. 【IT资讯】阿里新推出“阿里云网盘” 速度10MBs,百度网盘或迎来最强对手!
  6. 思考题目,仔细检查,外加一个ceil函数
  7. 正则表达式注意事项以及常用方法
  8. Java TheadLocal
  9. 前端学习(1504):组件通信的几种情况
  10. TurnipBit开发板DIY呼吸的吃豆人教程实例
  11. python中StringIO和BytesIO
  12. 编码器z相 C语言代码,编码器的Z相是什么?
  13. Abaqus相关报错合集
  14. ARP报文头部格式和请求流程
  15. 学生表mysql查询语句
  16. linux shrink dev sd,Virt相关命令(转)
  17. 万年历(C语言代码实现)
  18. linux查看主板最大内存容量,Linux 查看内存插槽数、最大容量的方法
  19. C++程序设计课程同步项目——循环结构程序设计项目任务一
  20. motoxt 1085 android8,Moto(Moto)X XT1085/全网通手机系统介绍评测-ZOL中关村在线

热门文章

  1. (ICASSP 19)AUTOMATIC GRAMMAR AUGMENTATION FOR ROBUST VOICE COMMAND RECOGNITION
  2. 『Others』一键关闭所有应用程序
  3. 华为MateBook D14 安装ubuntu16 wifi、蓝牙、触控板驱动问题解决
  4. 思科交换机命令大全(二)
  5. 一个免费的FLV编码工具(以及免费的FLV播放器)
  6. 中国高校鄙视链指南!
  7. 计算机网络(2)——标准化工作及相关组织
  8. 康耐视 visionpro图像角度识别
  9. BABvsBABAB
  10. python双星号是什么意思_Python字典前双星号(**)的作用