优化的原则如下:
1.更小的通常更好
一般情况下,应该尽量使用可以正确存储数据最小数据类型。
更小的数据类型通常更快,因为他们占用更少的磁盘、内存和CPU缓存,并且处理时需要的CPU周期更少。
2.简单就好
简单数据类型的操作通常需要更少的CPU周期。
例如:INT比VARCHAR操作代价低,因为字符集和校对规则(排序规则)使字符比较比INT比较更复杂。
⚠️使用MySQL内建的类型date/datetime/time而不是字符串来存储日期和时间
⚠️应该使用整型INT存储IP地址
3.尽量避免NULL
通常情况下最好指定列为Not Null,除非真的需要存储NULL值。
如果查询中包含可为NULL的列,MySQL优化比较难。因为可为NULL的列使得索引、索引统计和值比较都更复杂。 当可为NULL的列被索引时,每个索引记录需要一个额外的字节,在MyISAM里甚至还可能导致固定大小的索引变成可变大小的索引。 |
⚠️通常把可为NULL的列改为NOT NULL带来的性能提升比较小,但是若计划在列上建索引,就应该尽量避免设计可为NULL的列。
在可以满足值的范围的需求,并且预留未来增长空间的前提下,应该选择最小的数据类型。可使用如下技巧:
⚠️在MyISAM表里使用字符串作为标识列,默认会对字符串使用压缩索引导致查询慢很多。 对于完全“随机”的字符串也需要多加注意,如MD5()/SHA1()/UUID()产生的字符串。这些函数生成的新值会任意分布在很大的空间内,会导致INSERT以及一些SELECT语句变得很慢。 |
⚠️如果希望查询执行的快速且并发性好,单个查询最好在12个表以内做关联
范式的优缺点:
- 范式化的更新操作通常比反范式化更快
- 当数据较好地范式化时,就只有很少or没有重复数据,所以只需修改更少的数据
- 范式化的表通常更小,可以更好地放在内存里,所以执行操作会更快
- 很少有多余的数据意味着检索列表数据时更少需要DISTINCT或GROUP BY语句
⚠️范式化设计的schema的缺点就是通常需要关联。稍微复杂一些的查询语句在符合范式的schema上都可能需要至少一次关联。
⚠️单独的表使用更有效的索引策略。
反范式的优缺点:
若不需要关联表,则对大部分查询最差的情况:即使表没有使用索引,是全表扫描。 当数据比内存大时这可能比关联要快得多,因为避免了随机I/O。 |
ALTER TABLE操作(lock表且重建整张表)可能会导致MySQL服务不可用,对于常见的场景,能使用的技巧只有2种:
1.先在一台不提供服务的机器上执行ALTER TABLE操作,然后和提供服务的主库进行切换。
2.“影子拷贝”:用要求的表结构创建一张和源表无关的新表,然后通过重命名和删表操作交换两张表。