**更小的通常更好**
一般情况下,应该尽量使用可以正确存储数据的最小数据类型.更小的数据类型通常更快,因为他们占用更少的磁盘,内存和cpu缓存,并且处理时需要的cpu周期更少
但是要确保没有低估需要存储的值的范围,因为在schema中的多个地方增加数据类型的范围是一个非常耗时和痛苦的操作.
如果无法确定那个数据类型是最好的.要选择你认为不会超过范围的最小类型(如果系统不是很忙或者存储的数据量不多或者是在可以轻易修改设计的早期阶段)
**简单就好**
简单的数据类型的操作通常需要更少的cpu周期.例如,整形比字符操作代价更低.
因为字符集和校对规则(排序规则)使字符比较比整形比较更为复杂
这里有两个例子:一个是应该使用mysql内建的类型(date time datatime),而不是字符串来存储日期和时间,另外一个是应该用整形存储IP地址
**尽量避免使用null**
很多表都包含可为null的列,即使应用程序并不需要保持NULL也是如此,这是因为可为NULL是列的默认属性.
通常情况下最好指定列为not null,除非真的需要存储NULL值
如果查询中包含可为null的列,对mysql来说更难优化,因为可为null的列使得索引,索引统计和值比较都更复杂.可为null的列会使用更多的存储空间,在mysql中也要特殊处理
当可为null的列被索引的时候,每一个索引记录需要一个额外的字节,在myisam里甚至还可能导致固定大小的索引(例如只有一个整数列的索引)变成可变大小的索引
通常把可为null的列改为not null带来的性能提升的比较小,所以(调优时)没有必要首先在现有的schema中查找并修改掉这种情况,除非确定这会导致问题.
但是,如果计划在列上建索引,就应该尽量避免设计成可为null的列
Innodb使用单独的位(bit)存储NULL值,所以对于稀疏数据(很多值为null,只有少数行有非null值)有很好的空间效率.但是这不适用于myisam
例如datetime和timesamp列都可以存储相同类型的数据:时间和日期,精确到秒,然而timestamp只使用datetime一半的存储空间,并且会根据时区变化,具有特殊的自动更新能力
另一方面,timestamp允许的时间范围要小的多,有时候它的特殊能力会成为障碍
**慷慨是不明智**
使用`varchar(5)` 和 `varchar(200)` 存储 'hello' 的空间开销是一样的.那么使用更短的列有什么优势吗?
事实证明有很大的优势.更长的列会消耗更多的内存,因为mysql通常会分配固定大小的内存块来保存内部的值
尤其是使用内存临时表进行排序或操作时会特别糟糕.在利用磁盘临时表进行排序时也同样糟糕
所以最好的策略是分配真正需要的空间
**使用枚举(ENUM)代替字符串类型**
有时候可以使用枚举列代替常用的字符串类型.
枚举列可以把一些不重复的字符串存储成一个预定义的集合.
mysql在存储枚举时非常紧凑,会根据列表值的数量压缩到一个或者两个字节中
mysql在内部会将每个值在列表中的位置保存为整数,并且在表的.frm文件中保存"数字-字符串"映射关系的'查找表'
![](https://box.kancloud.cn/c6911ff3793124031852bc40e807b8f0_688x619.png)
一种绕过这种限制的方式是按照需要的顺序来定义枚举列,
另外也可以在查询中使 `field()` 函数显式的指定排序顺序,但这会导致mysql无法利用索引消除排序
![](https://box.kancloud.cn/f39a0c508601d742ec9bf617cce269c0_795x464.png)
我们用varchar和enum列的速度
![](https://box.kancloud.cn/696489fdd75f3bc9636873e619d926a7_329x151.png)
![](https://box.kancloud.cn/f8b008aa2c873183c853a239f046b14a_829x335.png)
- 书列表
- laravel框架关键技术
- 第一章 组件化开发与composer使用
- 简介
- composer
- 添加路由组件
- 添加控制器模块
- 添加模型组件
- 添加视图组件
- 第三章 laravel框架中常用的php语法
- 匿名函数
- 文件包含
- 魔术方法
- 魔术常量
- 反射
- 后期静态绑定
- traits
- 第四章 laravel框架中使用的HTTP协议基础
- HTTP协议
- 数据库
- 数据迁移
- 第六章 laravel框架中的设计模式
- IOC模式
- php核心技术与最佳实践
- 第一章面向对象核心
- 反射
- 简单ORM
- 异常和错误
- 接口
- 第二章,面向对象设计
- 设计原则
- 单一职责
- 接口隔离
- 开放封闭
- 替换原则
- 依赖倒置
- linux是怎么写的呢?
- 第三章 正则表达
- 认识正则
- 第四章 php网络技术应用
- HTTP协议详解
- php和http相关函数
- 垃圾信息防御措施
- 现代操作系统
- 引论
- sql必知必会
- 限制结果
- 按位置排序
- where求职顺序
- IN操作符
- like
- 函数
- group by
- 组合查询
- 插入检索出的数据
- 视图
- 高性能mysql
- 第一章节 mysql架构与历史
- mysql架构逻辑图
- 连接与管理
- 优化与运行
- 读写锁
- 锁粒度
- 表锁(table lock)
- 行级锁(row lock)
- ACID
- 隔离级别
- 死锁
- 隐式和显式锁定
- 多版本并发控制
- Innodb概览
- 第四章节 Schema与数据类型优化
- 选择优化的数据类型
- 日期和时间类型
- 标识列
- 特殊类型数据
- 表设计中的缺陷
- 范式
- 计数器表
- 第五章 创建高性能索引
- 索引基础
- 索引类型
- 索引的优点
- 高性能索引策略
- 选择合适的索引列顺序
- 聚簇索引
- 顺序的主键什么时候会造成更坏的后果
- 覆盖索引
- 使用索引扫描来做排序
- 压缩索引
- 冗余和重复索引
- 索引和锁
- 支持多种过滤条件
- 什么是范围条件
- 优化排序
- 维护索引和表
- 表损坏
- 减少索引和数据的碎片
- 第六章 查询性能优化
- 扫描的行数和访问类型
- 重构查询方式
- 查询执行的基础
- 重构-改善既有代码设计
- 第一章-重构
- 什么是重构
- 第一个案列
- 重构第一步
- 王垠博客
- 多态取代价格相关逻辑