Schema Optimization and indexing

 Mysql数据类型

1. 选择合适的类型
越小越好:确定数据精度后,选择小的类型
简单:选择需要更少cpu时钟,integer比较比string消耗少,使用内置date/timestamp而非string
尽量使用not null:mysql对于nullable的列很难优化(使index index策略 比较更加复杂)
使用更多空间,需要在mysql内部特殊处理,加索引每行还需要一个额外的字节,即使确实可以null,考虑是否可用0 空串等
2. whole number
TINYINT, SMALLINT, MEDIUMINT, INT,or BIGINT
int(1),int(20)对应用和计算是没意义的,主要用于交互式的client显示用
3. Real number
decimal(也可存储bigint不能存的整数),float,double
float double提供近似精确的浮点运算:具体的如何计算要参考系统的浮点实现
4. string
varchar:省空间,但是如果update后原空间不够,需要额外空间存储,不同引擎实现不同
char:固定长度,对经常变动和短列效率更高
字符分配越少越好:varchar(100)会在内测分配固定大小的空间,sort group等操作也会使用内存临时表
blob text:会特殊存储 排序等操作也会特殊处理;mysql不能用全部字段做索引 max_sort_length
    在EXPLAIN中包含”Using temporary“时,说明使用了隐式的临时表:内存引擎不支持blob text,生成on-disk临时表,很耗性能
使用ENUM代替string: 最大缺点是list是固定的,join时由int转为string也会增加负担,但因为字节短而抵消部分
5. date and times
datetime:以YYYYMMDDHHMMSS存储时间,8字节,与zone无关
timestamp:1970以来的秒数,时间显示与zone有关
6. 选择主键
所有关联表的主键相同
integer最好的选择,尽量避免string(比int慢),
索引
1. 两列索引:mysql只能有效搜索最左侧的列
2. 索引类型
b-tree
完全匹配,匹配最左、最左开头、最左范围、最左全匹配其他range、index-only
缺点:仅最左、不能跳过中间column、
hash index
用于精确查询index中的所有列
只有MemoryEngine支持显示的hashIndex,也是Memory table的默认index
缺点:必须去查实体row,无法排序,不支持部分key匹配,只支持in(),=;index维护慢
适用:memeryEngine、NDB cluster engine(unique hash index),innodb(adaptive hash index)自动将b-tree上建,不可控制
Spatial (R-Tree) indexes:
MyISAM支持,可以使用地理类型(GEOMETRY), 
不需要使用where去操作最左列,数据会在各种维度建立index
必须用mysql GIS函数使用,比如MBRCONTAINS()
Full Text Index
MyISAM的一种特殊index,它查找key words而不是直接匹配index中的值
It has many subtleties, such as stopwords, stemming and plurals, and Boolean searching
索引策略
1. 隔离列
不要把列作为表达式或函数内 使用
2. prefix index:用前n个字符作为索引,选择性:1/n到1 反应index的选择能力
3. cluster index:不同engine存放数据格式不同,innoDB主键有序对性能、存储大小有关
4. covering index:query的列全在index中
更小、有序、会做cache、对innoDb更有效(由于clustered index)
在Explain中,type=index指的是查询的方式,Extra=index指的是covering index
5. 使用index scan做排序
6. Packed (Prefix-Compressed) Indexes:Compressed blocks use less space, but they make certain operations slower
7. index与锁:innoDb中index使查询锁住较少的row
 
索引和表的维护
1. 三个问题:寻找修复损害的表,维护索引精确的统计信息,减少片段(fragmentation)
2. 寻找修复损害的表
CHECK TABLE
REPAIRE TABLE:担不是所有表都支持
离线使用引擎相关的工具修复:myisamchk
3. 更新索引统计信息
查询优化器使用两个函数查询表,分析数据,决定如何使用index:records_in_range() info()
如果提供信息不准确:ANALYZE TABLE,但是不同engine作用不同
内测engine:不使用统计信息
MyIsam:使用存储在disk的信息,分析时全表扫描,会锁住表
InnoDB:统计信息不存储在disk,在table打开时用随机index分析,统计信息也不准确;一般不用分析,如果长时间运行可以使用,而且可以online,不会锁表
4. 减少索引及数据片段
虽然b-tree是随机disk访问的,但是leaf如果顺序、紧凑性能会更好;如果碎片化,随机访问和全索引扫描会成倍减慢,尤其对coving-index
两种方法减少碎片:OPTIMIZE TALBE; dump and reload
标准化与非标准化(Normalization and Denormalization)
1. 是否满足范式
加速alter table
1. mysql任何对表结构的修改都会导致table rebuild
慢:ALTER TABLE xx MODIFY COLUMN rental_duration TINYINT(3) NOT NULL DEFAULT 5
快:ALTER TABLE XX ALTER COLUMN rental_duration SET DEFAULT 5(只修改.frm文件)
2. 以下操作可以使用.frm 避免rebuild table
remove(非add)AUTO_INCREMENT 属性
删除、修改Enum、set常量
3. 快速建立MyISam index
mysql> ALTER TABLE test.load_data DISABLE KEYS;
-- load the data
mysql> ALTER TABLE test.load_data ENABLE KEYS;
这样会在data都load后build index,更快,index碎片化、紧凑
对unique index无效
 
存储引擎需要注意的问题
1. MyISAM
table级别的lock
没有自动数据恢复机制
无事务
只有index被缓存在Mysql进程中,数据由操作系统缓存,调用很昂贵
结构紧凑,占用disk少,全表扫描快
2. Memory
table级别的lock
不支持动态长度的列,varchar(5000)会存为char(5000)很占内存
默认hash index
没有index 统计:复杂查询可能导致较差的执行计划
重启数据丢失
3. InnoDb
支持事务
对于mysql5.0,他是唯一一个支持外键的stock storage engine 
行级锁
MVCC实现并发
?Clustering by primary key
所有index包含主键列:如果主键列很长 index会很大
优化缓存:index data都会缓存,智能添加hash index
index unpacked:比MyISAM的index大
data load慢:build index 一次一行,而非by sorting
不会缓存count(*):count* 会全表扫描

你可能感兴趣的:(mysql,职场,index,休闲)