表的优化
- 定长和变长字段分离
核心且常用字段,用定长, 放在一张表里
varchar text blob等字段,单放一张表,用主键和核心表关联起来 - 常用字段和不常用字段分离
- 需要关联统计的字段上, 添加冗余字段。并不一定需要按照范式标准。
列类型选择
- 字段类型优先级
整型>date,time>enum,char>varchar>blob,text - 够用就行,不要慷慨
- 尽量不要用NULL
查询不方便,甚至在低版本上占用更多空间
索引优化策略
- 索引类型
1.1 B树索引
1.2 Hash索引
hash的理论查询时间为O(1)
既然hash如此高效,为何不用hash索引:hash函数计算后的结果是随机的(如果在磁盘上放置数据,随着ID增长, ID对应的行的数据在磁盘上位置随机)。无法对范围查询进行优化,无法对前缀利用前缀索引,排序无法优化 - 索引使用
假如有个联合索引 (a,b,c), 以下where情况能不能使用到索引:
a = 3 and b = 'hello' and c = 5
a = 3 and b > 'hello' and c = 5
a = 3 and b like 'hello%' and c = 5
a = 3 and b like '%hello' and c = 5
a = 3 and c = 5
a = 3 and c > 5 order by b; (索引不仅能提高查询速度, 也能提高排序速度) - 聚簇和非聚簇索引
myisam(非聚簇)和innodb(聚簇),都是B树索引。具体细节不同点:
myisam索引文件.myi和数据.myd不再一个文件。主索引和次索引都指向物理行(磁盘位置)
innodb的主索引文件上,直接存放该行数据,成为聚簇索引。次索引指向主键的引用。
对于innodb来说:
- 主键索引,既存储索引值,又在叶子中存储行的数据
- 如果没有主键,则用unique key做主键
- 如果没有unique key, 则系统生成一个row id做主键
- 索引覆盖
如果查询的列恰好是索引的一部分, 那查询只需要在索引文件上运行, 不需要回行到磁盘再找数据 - 理想的索引
查询频繁、区分度高、长度小、尽量覆盖常用查询字段。
主键索引尽量用自增ID
左前缀索引(选用合适的长度即可)
左边类似,可以用倒叙,或者伪哈希
多列索引(考虑顺序、区分度) - 索引和排序
注意 filesort. - 重复索引和冗余索引
sql语句优化
explain:
select type:
type: 索引利用率
possible_keys:可能用到的键
key:肯定用到的键
key_len:用到键的长度
ref:引用关系(比如说两表联查时)
rows:估计扫描行数
type性能比较重要
all --所有数据
index---索引查询
range---索引范围查询
ref----通过索引直接引用
in-ref
null count system优化到常量级别
in 子查询 exists子查询陷阱
count优化
union总是产生临时表
limit优化
show profiles // 统计性能