高性能MySQL读书笔记 (三)
来源:SegmentFault
2023-01-20 09:14:52
0浏览
收藏
在数据库实战开发的过程中,我们经常会遇到一些这样那样的问题,然后要卡好半天,等问题解决了才发现原来一些细节知识点还是没有掌握好。今天golang学习网就整理分享《高性能MySQL读书笔记 (三)》,聊聊MySQL,希望可以帮助到正在努力赚钱的你。
1. schema与数据类型优化
1.1 数据类型选择
更小: 选择不超过需求范围的最小类型
更简单
避免使用Null: 含有Null列会使索引,索引统计和值更为复杂
分配空间: 根据实际需要分配.使用内存临时表或操作时会比较糟糕
特殊类型:书中举例,ip地址应该用无符号整数存储,MySQL提供inet_aton, inet_ntoa方法转换
1.2 schema 设计陷阱
- 太多列,存储引擎api需要在服务器层和存储引擎层通过行缓冲格式拷贝数据,然后解码.转换代价依赖于列的数量
- 太多的关联,单个查询最好在12个表以内
- 最好不用枚举enum
- 可以使用其他"空值"替代Null
1.3 范式和反范式
- 范式化: 每个事实数据只出现一次
- 反范式化: 信息是冗余的
- 第一范式1NF: 关系中的每个属性都不可再分
- 第二范式2NF: 每个表中的非主属性完全依赖于码(例如主键, 可以唯一决定属性集合)
- 第三范式3NF: 消除非主属性之间的依赖关系,只保留非主属性与码的依赖关系
- 范式化优点: 更新操作更快,占用空间更小
- 范式化缺点: 表的关联查询更多
- 混用范式和反范式: 从父表冗余一些数据到子表有利于排序, 缓存衍生值减少子查询计算
1.4 缓存表和汇总表
业务上有时需要一张完全独立的汇总表或缓存表主要用于满足检索的需求
- Flexviews实现物化视图,可以增量重新计算物化视图的内容
- 计数器表: 如果需要在表中保存计数器,更新计数器时,会有全局的互斥锁.要获的高并发更新的性能,可以将计数器保存在多行,每次随机选择一个进行更新
1.5 修改表结构
- 大部分的alter table操作将导致服务中断
- 所有的modify column 操作都将导致表重建
- 可以新建一个.frm文件为修改后的表结构,替换原来的.frm文件避免表重建
2. 创建高性能的索引
索引是存储引擎用于快速查找记录的数据结构
2.1 索引基础
MySQL中,存储引擎先在索引中找到对应值根据匹配的索引记录找到对应的数据行.索引在存储引擎层实现
2.1.1 B-Tree索引
- 目前大部分数据库系统及文件系统都采用B-Tree或其变种B+Tree作为索引结构.
- InnoDB使用B+Tree, NDB集群存储引擎实际使用T-Tree. 索引对多个值的排序一句是根据表定义索引时列的顺序.
- 索引对如下类型的查询有效
- 全值匹配
- 匹配最左前缀,只使用索引第一列
- 匹配列前缀: 只匹配某一列值的开头部分
- 匹配范围值
- 精确匹配某一列并范围匹配另外一列
- 只访问索引的查询: 查询只需要访问索引无需访问数据行(覆盖扫描)
- 限制
- 如果不是按照索引的最左列开始,则无法使用索引
- 不能跳过索引中的列,即定义索引(a,b,c),则使用a,c查询条件时,只能使用索引第一列
- 如果查询中有某个列的范围查询,则右边所有的列都无法使用索引优化查找
2.1.2 哈希索引
- 对于每一行数据,存储引擎会对索引列计算一个哈希码.索引包含哈希码和行指针
- MySQL中只有Memory存储引擎支持
- 限制
- 不能使用索引中的值避免读取行
- 无法用于排序
- 不支持部分索引列匹配查找
- 不支持范围查询
- 出现哈希冲突时会扫表
2.1.3 伪哈希索引
- 应用: 当存储引擎不支持哈希索引,在B-Tree基础上使用哈希值索引查找
- 场景: 需要存储大量的url并根据url进行搜索查找
- 问题: 如果使用B-Tree存储,内容很大
- 方案: 删除url列索引,新增一个被索引的url_crc列,使用CRC32做哈希.
- sql: select id from t_url where url="https://www.google.as/" and url_crc=CRC32("https://www.google.as/")
- 结果: MySQL优化器会使用选择性很高体积很小的基于url_crc索引完成查找
- 缺陷: 需要维护哈希值, crc32表大时会出现大量冲突
- 注意: 不要使用SHA1和MD5做哈希函数,因为计算出来的哈希值比较长; 必须在where子句中包含常量
- 插件: 移植自Percona Server的FNV64可以在MySQL中作为哈希函数使用
2.1.4 空间数据索引(R-Tree)
- MyISAM表支持空间索引,可以用作地理数据存储
2.1.5 全文索引
- 全文索引是一种特殊类型索引,查找文本中的关键词,后续讨论
2.1.6 其他
- TokuDB 使用分形树索引, 对于InnoDB的讨论也适用于TokuDB
- ScaleDB 使用Patricia tries
- InfiniDB和Infobright使用一些特殊的数据结构优化某些特殊的查询
2.2索引的优点
- 减少扫描数据量
- 避免排序和临时表
- 将随机I/O变成顺序I/O
- 对于TB级别的数据,经常会使用块级别的数据技术来替代索引
2.3 高性能的索引策略
2.3.1 独立的列
- 索引列不能是表达式一部分或函数参数,否则不能使用索引
2.3.2 前缀索引
- 场景: 需要索引很长的字符列,这会让索引变得大且慢
- 方案: 根据业务找到最适合的前缀长度,创建前缀索引
- 优点: 索引更小,更快
- 缺点: MySQL无法使用前缀索引order by 和group by,也无法使用前缀索引做覆盖扫描
- 常见: 用16进制唯一id存储session id,如果采用长度为8的前缀索引能显著提升性能
2.3.3 多列索引
- MySQL的索引合并(index merge)策略,一定程度上可以使用多个单列索引定位
- where查询条件的列最好使用多列索引而不是单独列单独索引
2.3.4 选择合适的索引顺序
- 将选择性最高的列放在索引最前列
- 性能不只依赖于所有索引列的选择性,也和查询条件的具体值分布有关,可能需要根据运行频率最高的查询调整索引列顺序
- 有时需要根据排序,分组和范围条件综合考虑
2.3.5 聚簇索引
- 聚簇索引并不是单独的索引类型,而是一种数据存储方式.叶子页包含行的全部数据,节点页只包含索引列
- InnoDB默认使用主键聚集数据,如果没有会选择一个唯一的非空索引作为聚簇索引
- 可以把相关数据保存一起,减少磁盘I/O
- 数据访问更快
- 插入速度严重依赖插入顺序
- 更新聚簇索引代价高
- 可能面临"页分裂"问题,导致占用更多磁盘空间
- 可能导致全表扫描变慢,由于行比较稀疏或页分裂导致数据存储不连续
- 二级索引变大,二级索引访问需要两次索引查找
2.3.6 覆盖索引
- 如果一个索引包含所有需要查询的字段的值
- 覆盖索引必须要存储索引列的值
- MySQL不能在索引中执行like 操作,但能在索引中做最左前缀匹配的like比较,因为可以转换为简单的比较操作
- 延迟关联: 先通过覆盖索引返回需要的主键再通过这些主键关联原表获得需要的行
2.3.7 使用索引扫描做排序
- 只有索引列的顺序和order by 子句的顺序一致时才能使用索引对结果做排序
- 如果关联多表,则只有当order by子句引用的字段全部为第一个表时才能使用索引排序
2.3.8 压缩索引
- MyISAM使用前缀压缩减少索引的大小
- create table 时通过指定pack_keys控制压缩方式
2.3.9 未使用的索引
- 通过查询INFORMATION_SCHEMA.INDEX_STATISTICES能查到每个索引的使用频率
- 冗余和重复的索引会降低性能
2.3.10 索引和锁
- InnoDB在二级索引上使用共享(读)锁,但访问主键索引需要排他(写)锁,消除了使用覆盖索引的可能
2.4 维护索引和表
- check table 通常能够找出大多数的表和索引的错误
- MyISAM表易损坏,InnoDB不容易,损坏可能是硬件或人为错误
- MySQL查询优化器通过两个api,一个获取范围大概数据量,一个返回各种类型的数据包括索引基数
- 减少索引和数据的碎片,B-TREE索引可能碎片化,这会降低效率
到这里,我们也就讲完了《高性能MySQL读书笔记 (三)》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于mysql的知识点!
版本声明
本文转载于:SegmentFault 如有侵犯,请联系study_golang@163.com删除

- 上一篇
- 高性能MySQL读书笔记 (四)

- 下一篇
- 关于Mysql中on条件和where条件的使用总结
查看更多
最新文章
-
- 数据库 · MySQL | 4小时前 | 索引 数据类型 约束 主键 CREATETABLE
- MySQL建表命令详解:CREATETABLE示例及解释
- 206浏览 收藏
-
- 数据库 · MySQL | 19小时前 | 数据类型 扩展性 存储引擎 CREATETABLE 约束条件
- MySQL建表攻略:详解数据表创建方法
- 265浏览 收藏
-
- 数据库 · MySQL | 23小时前 | mysql 字符集 中文乱码 utf8mb4 utf8mb4_unicode_ci
- MySQL中文乱码解决方案与字符集修改命令大全
- 339浏览 收藏
查看更多
课程推荐
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
查看更多
AI推荐
-
- 笔灵AI生成答辩PPT
- 探索笔灵AI生成答辩PPT的强大功能,快速制作高质量答辩PPT。精准内容提取、多样模板匹配、数据可视化、配套自述稿生成,让您的学术和职场展示更加专业与高效。
- 24次使用
-
- 知网AIGC检测服务系统
- 知网AIGC检测服务系统,专注于检测学术文本中的疑似AI生成内容。依托知网海量高质量文献资源,结合先进的“知识增强AIGC检测技术”,系统能够从语言模式和语义逻辑两方面精准识别AI生成内容,适用于学术研究、教育和企业领域,确保文本的真实性和原创性。
- 38次使用
-
- AIGC检测-Aibiye
- AIbiye官网推出的AIGC检测服务,专注于检测ChatGPT、Gemini、Claude等AIGC工具生成的文本,帮助用户确保论文的原创性和学术规范。支持txt和doc(x)格式,检测范围为论文正文,提供高准确性和便捷的用户体验。
- 37次使用
-
- 易笔AI论文
- 易笔AI论文平台提供自动写作、格式校对、查重检测等功能,支持多种学术领域的论文生成。价格优惠,界面友好,操作简便,适用于学术研究者、学生及论文辅导机构。
- 48次使用
-
- 笔启AI论文写作平台
- 笔启AI论文写作平台提供多类型论文生成服务,支持多语言写作,满足学术研究者、学生和职场人士的需求。平台采用AI 4.0版本,确保论文质量和原创性,并提供查重保障和隐私保护。
- 41次使用
查看更多
相关文章
-
- golang MySQL实现对数据库表存储获取操作示例
- 2022-12-22 499浏览
-
- 搞一个自娱自乐的博客(二) 架构搭建
- 2023-02-16 244浏览
-
- B-Tree、B+Tree以及B-link Tree
- 2023-01-19 235浏览
-
- mysql面试题
- 2023-01-17 157浏览
-
- MySQL数据表简单查询
- 2023-01-10 101浏览