1.数据字段类型
链接:http://www.jianshu.com/p/17a12c79448fa、尽量使用TINYINT、SMALLINT、MEDIUM_INT作为整数类型而非INT,如果非负则加上UNSIGNED,VARCHAR的长度只分配真正需要的空间;
b、尽量少使用DOUBLE和DECIMAL类型;
c、时间类型上,尽量使用TIMESTAMP而非DATETIME,其存储空间只需要DATETIME类型的一半;
d、单表不要有太多字段,建议在20以内;
e、尽量设置NOT
NULL,避免使用NULL字段,NULL字段很难查询优化且占用额外索引空间;
f、使用枚举或整数代替字符串类型;
2.添加索引以及索引原理
(1)索引的本质
“索引(Index)是帮助MySQL高效获取数据的数据结构。提取句子主干,就可以得到索引的本质:索引是数据结构。”
(2)MySQL两种存储引擎的索引实现
MyISAM索引和数据部分是分离的,索引文件仅保存的是数据记录的地址。而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。
第二个与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域。
(3)通过索引优化sql性能方法
链接:http://www.jianshu.com/p/17a12c79448fa、应尽量避免在WHERE子句中对字段进行NULL值判断,否则将导致数据库存储引擎放弃使用索引而进行全表扫描;
b、索引不是越多越好,根据业务代码的查询有针对性的创建,考虑在WHERE、ORDER/GROUP
BY命令上涉及的列建立索引,同时通过MySQL的执行计划命令EXPLAIN(关于执行计划的EXPLAIN下文会讲到)来查看自己的SQL语句是否落到索引上还是执行全表扫描;字段值分布很稀少的字段不适合建索引,例如"性别"这种只有两个值的枚举字段;
c、字符串值的字段只需建前缀索引(最左前缀匹配);同时该类字段最好不要用做主键;
d、尽量不用外键,由业务代码约束保证;
e、使用多列索引时主意顺序和查询条件保持一致,同时删除不必要的单列索引;
f、合理地使用覆盖索引,避免不必要地回表操作;
3.EXPLAIN的具体用法
链接:http://www.jianshu.com/p/17a12c79448fa、key:指出优化器选择使用的索引。一般来说SQL查询中的每个表都仅使用一个索引。也存在索引合并的少数例外情况,如给定表上用到了两个或者更多索引;
b、rows:提供了QEP试图分析所有存在于累计结果集中的行数目的MySQL优化器估计值。QEP很容易描述这个很困难的统计量;
c、possible_keys:指出SQL优化器为查询选定的索引;
d、key_len:定义用于SQL语句的连接条件的键的长度;
e、table:EXPLAIN命令输出结果中的一个单独行的唯一标识符。这个值可能是表名、表的别名或者一个为查询产生临时表的标识符;
f、select_type:提供了各种表示table列引用的使用方式的类型。最常见的值包括SIMPLE(不包含子查询和其他复杂语法的简单查询)、PRIMARY(为复杂查询创建的首要表)、DERIVED(当查询的表不是物理表时,那么就用该关键字标识)、UNION(执行union的sql语句的SQL元素)、DEPENDENT SUBQUERY(为使用子查询而定义的);
g、Extra:提供了有关不同种类的MySQL优化器路径的一系列额外信息;
h、type:代表QEP中指定的表使用的连接方式,const(当前表只有一行匹配时出现该关键字)、eq_ref(表示有一行是为每个之前确定的表而读取的)、ref(表示所有具有匹配的索引值的行都被用到)、range(所有符合一个给定范围值的索引行都被用到)、ALL(表示需要一次全表扫描其他类型的值);
i、ref:可以被用来标识那些用来进行索引比较的列或者常量;