1、强制使用decimal存储小数,不使用float、double,防止精度损失,如果存储的数据范围超过 decimal 的范围,建议将数据拆成整数和小数分开存储。这也是阿里的强制开发规范。
2、高效分页
limit m,n其实质就是先执行limit m+n,然后从第m行取n行,这样当limit翻页越往后翻m越大,性能越低。比如
select * from A limit 100000,10,这种sql语句的性能是很差的,建议改成下面的版本:
selec id,name,age from A where id >=(select id from A limit 100000,1) limit 10
3、InnoDB的行锁加上死锁检测机制会导致数据库CPU短时间内被占满,导致整库几乎无法响应。
4、对数据分组的总结:
1 分组函数只能出现在选择列表、having、order by子句中(不能出现在where中) 。
2 如果在select语句中同时包含有where,group by, having, order by 那么它们的顺序是where,group by, having, order by 。
3 在选择列中如果有列、表达式和分组函数,那么这些列和表达式必须有一个出现在group by 子句中,否则就会出错。
如SELECT deptno, AVG(sal), MAX(sal) FROM emp GROUP by deptno HAVING AVG(sal) < 2000;
这里deptno就一定要出现在group by 中。
5、sql排序默认是升序(从小到大),直接order by,降序是desc。
6、子查询比关联查询效率高。
MySQL:
mysql的innodb的底层存储模型是B+树,它使用主键作为聚簇索引,使用插入的数据作为叶子节点,通过主键可以很快找到叶子节点,从而快速获取记录。主键最好要自增。因为自增主键可以让插入的数据按主键顺序插入到底层的B+树的叶子节点中,由于是按序的,这种插入几乎不需要去移动已有的其它数据,所以插入效率很高。如果主键不是自增的,那么每次主键的值近似随机,这时候就有可能需要移动大量数据来保证B+树的特性,增加了不必要的开销。
对于mysql的join,它用的是Nested Loop Join算法,也就是通过前一个表查询的结果集去后一个表中查询,比如前一个表的结果集是100条数据,后一个表有10W数据,那么就需要在100*10W的数据集合中去过滤得到最终的结果集。因此,尽量用小结果集的表去和大表做join,同时在join的字段上建立索引,如果建不了索引,就需要设置足够大的join buffer size