mysql-优化总结

1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by,group by 涉及的列上建立索引.

2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如

select id from t where num is null

最好不要给数据库留NULL,尽可能的使用 NOT NULL填充数据库.

3.应尽量避免在 where 子句中使用!=或<>操作符, MySQL只有对以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE。

4.应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描, 可以 使用UNION合并查询:

select id from t where num=10 union all select id from t where num=20

5.in 和 not in 也要慎用,否则会导致全表扫描,对于连续的数值,能用 between 就不要用 in 了:

select id from t where num between 1 and 3

6.前导模糊查询不能使用索引。
下面的查询也将导致全表扫描:

select id from t where name like ‘%abc%’ 
或者
select id from t where name like ‘%abc’

若要提高效率,可以考虑全文检索。
下面的查询会用到索引:

select id from t where name like ‘abc%’

7.如果在 where 子句中使用参数,也会导致全表扫描。

8.应尽量避免在 where 子句中对字段进行表达式操作或者函数操作

如:select id from t where num/2 = 100
应该改为:select id from t where num = 100*2

9.索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。

10.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。

  1. 任何地方都不要使用
select * from t ,

用具体的字段列表代替“*”,不要返回用不到的任何字段。

常见的简化规则如下:不要有超过5个以上的表连接(JOIN),考虑使用临时表或表变量存放中间结果。少用子查询,视图嵌套不要过深,一般视图嵌套不要超过2个为宜

12.法则:不要在建立的索引的数据列上进行下列操作:

◆避免对索引字段进行计算操作

◆避免在索引字段上使用not,<>,!=

◆避免在索引列上使用IS NULL和IS NOT NULL

◆避免在索引列上出现数据类型转换

◆避免在索引字段上使用函数

◆避免建立索引的列中使用空值。

◆数据区分度不大的字段不易使用索引–例如:性别只有男,女,订单状态,每次过滤数据很少

复合索引最左前缀原则–例如user 表建立了(userid,phone)的联合索引
有如下几种写法:

(1)select * from user where userid = ? and phone = ?
(2)select * from user where phone=? and userid= ?
(3)select * from user where phone = ?
(4)select * from user where userid = ?
其中(1)(2)(4)可以命中索引,(3)会导致全表扫描

13.明知道只有一条记录返回,建议加上limit 1

14.单表不要有太多字段,建议在20以内

15.OR改写成IN:OR的效率是n级别,IN的效率是log(n)级别,in的个数建议控制在200以内

如果你把你的表锁上一段时间,比如30秒钟,那么对于一个有很高访问量的站点来说,这30秒所积累的访问进程/线程,数据库链接,打开的文件数,可能不仅仅会让你的WEB服务崩溃,还可能会让你的整台服务器马上挂了。

所以,如果你有一个大的处理,你一定把其拆分,使用 LIMIT oracle(rownum),sqlserver(top)条件是一个好的方法。下面是一个

mysql示例:
while(1){

   //每次只做1000条  
   mysql_query(“delete from logs where log_date <= ’2012-11-01’ limit 1000”);

   if(mysql_affected_rows() == 0){
     //删除完成,退出!    
     break;
  }
  
  //每次暂停一段时间,释放表让其他进程/线程访问。
  usleep(50000)

}

16.强制类型转换会全表扫描

如果 phone 字段是 varchar 类型,则下面的 SQL 不能命中索引。

 select * fromuser where phone=13800001234

可以优化为:

select * fromuser where phone='13800001234'
  1. 尽量少使用子查询.
例:SELECT * FROM t1 WHERE id (SELECT id FROM t2 WHERE name='hechunyang');

子查询在MySQL5.5版本里,内部执行计划器是这样执行的:先查外表再匹配内表,而不是先查内表t2,当外表的数据很大时,查询速度会非常慢。

在MariaDB10/MySQL5.6版本里,采用join关联方式对其进行了优化,这条SQL会自动转换为

SELECT t1.* FROM t1 JOIN t2 ON t1.id = t2.id;

但请注意的是:优化只针对SELECT有效,对UPDATE/DELETE子查询无效,固生产环境应避免使用子查询

发布了24 篇原创文章 · 获赞 8 · 访问量 933

猜你喜欢

转载自blog.csdn.net/kaihuishang666/article/details/99583167