标签:explain 更新 rand user 提交 根据 tar buffer 内存
1.对于复杂查询,例如报表等多join的查询,尽量使用缓存,使用缓存的时候注意,now(),Randy(),currDate()等变化的函数是无法使用缓存,例如:SELECT username FROM user WHERE signup_date >= CURDATE(),可以使用变量代替函数(PHP);
2.对于复杂查询可以使用EXPLAIN解释优化sql,从数据量、索引等方面对sql进行优化处理。
3.对于确定返回一条数据的sql请使用limit 1;
4.关于索引,使用like ‘%username%’ 是无法应用索引的,可以将username建立fulltext索引以提高效率;两个表关联尽量使用索引关联,注意关联字段数据类型必须一致,否则是无法应用索引;
针对索引:列出一些常用技巧
负向条件查询不能使用索引;
前导模糊查询不能使用索引,fulltext类型索引除外,非前导模糊查询例如like ‘username%’则可以应用索引;
列计算不能应用索引,例如sum(column);
组合索引的顺序不影响索引触发,比如组合索引a b c,使用b a c ,b a,a都会命中索引,在创建多列索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边;
频繁更新的列上不能建立索引,因为索引修改会比普通列产生更大的开销。
5.关于随机条数,不能使用select from table order by rand() limit 来实现,效率极低;不能把rand应用在order中!关于随机条数可以使用自定方案来获取,例如:
select username from table t1 join(select round(Rand()*(select max(id) from table)) as id) as t2 where t1.id>=t2.id limit 20;
6.绝对不能直接select *!可以使用select count(*) 来获取数据量,或者返回具体字段例如:select username from ...;
7.推荐使用PROCEDURE ANALYSE() 来优化你的表结构,尤其是你的表字段很多的时候。
8.针对大数据的insert 和delete操作,尽量拆分成多个数据操作进行,否者。后果。。。。啧啧啧。
9.针对mysql的INNODB引擎,支持事物方面,主要是采用redo log和undo log来实现事物的回滚和提交;
任何针对数据库的修改都会先写入一个叫buffer pool的缓存当中,由专门的刷新线程将修改数据阶段性刷新到磁盘从而持久化数据,但当刷新的过程中,数据库非正常中断,会造成数据丢失,为避免这样的数据丢失,mysql引入re-do log来记录数据修改,在非正常中断发生后能够恢复数据到一个正确的状态,但是会增加写入re-do log的开销。
摘一段例子:
假设有2个数值,分别为A和B,值为1,2
1. start transaction;
2. 记录 A=1 到undo log;
3. update A = 3;
4. 记录 A=3 到redo log;
5. 记录 B=2 到undo log;
6. update B = 4;
7. 记录B = 4 到redo log;
8. 将redo log刷新到磁盘
9. commit
在1-8的任意一步系统宕机,事务未提交,该事务就不会对磁盘上的数据做任何影响。如果在8-9之间宕机,恢复之后可以选择回滚,也可以选择继续完成事务提交,因为此时redo log已经持久化。若在9之后系统宕机,内存映射中变更的数据还来不及刷回磁盘,那么系统恢复之后,可以根据redo log把数据刷回磁盘。
所以,redo log其实保障的是事务的持久性和一致性,而undo log则保障了事务的原子性。
10.基础数据集应尽量少,避免全表数据查询。
未完待续。。。。。嘎嘎嘎。。。
标签:explain 更新 rand user 提交 根据 tar buffer 内存
原文地址:http://www.cnblogs.com/vijayblog/p/7754943.html