设计表时要注意:
1.表字段避免null值出现,null值很难查询优化且占用额外的索引空间,推荐默认数字0代替null。
2.使用整数代替字符串类型
3.单表不要有太多字段,建议在20以内
4.索引并不是越多越好,要根据查询有针对性的创建,考虑在WHERE和ORDER BY命令上涉及的列建立索引,可根据EXPLAIN来查看是否用了索引还是全表扫描
5.应尽量避免在WHERE子句中对字段进行NULL值判断,否则将导致引擎放弃使用索引而进行全表扫描
6.值分布很稀少的字段不适合建索引,例如"性别"这种只有两三个值的字段
7.字符字段最好不要做主键
8.尽量不用UNIQUE,由程序保证约束
9.使用多列索引时主意顺序和查询条件保持一致,同时删除不必要的单列索引,使用合适的数据类型,选择合适的索引,根据查询条件,建立索引,优化索引、优化访问方式,限制结果集的数据量。注意填充因子要适当(最好是使用默认值0)。索引应该尽量小,尽量使用字节数小的列建索引,不要对有限的几个值的列建单一索引。
10.避免select *,将需要查找的字段列出来,如果返回不必要的数据,则浪费了服务器的I/O资源,加重了网络的负担,降低了性能。如果表很大,在表扫描期间将表锁住,禁止其他的联结访问表,后果很严重。
11.使用连接(join)来代替子查询
12.拆分大的delete或insert语句
13.可通过开启慢查询日志来找出较慢的SQL(祝配合)
14.不做列运算:SELECT id WHERE age + 1 = 10,任何对列的操作都将导致表扫描,它包括数据库教程函数、计算表达式等等,查询时要尽可能将操作移至等号右边
15.sql语句尽可能简单:一条sql只能在一个cpu运算;大语句拆小语句,减少锁时间;一条大sql可以堵死整个库
16.OR改写成IN:OR的效率是n级别,IN的效率是log(n)级别,in的个数建议控制在200以内, 在IN后面值的列表中,将出现最频繁的值放在最前面,出现最少的放在最后面,减少判断的次数
17.尽量避免用函数和触发器,在应用程序实现, 注意使用DISTINCT,在没有必要时不要用,它同UNION一样会使查询变慢。 一般在GROUP BY和HAVING子句之前就能剔除多余的行,所以尽量不要用它们来做剔除行的工作,也就是说尽可能在WHERE中过滤数据。
18.避免like查询,最好做到精确查询,例如产品列表
19.使用同类型进行比较,比如用'123'和'123'比,123和123比,避免‘123’与123对比
20.尽量避免在WHERE子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描,避免全表查询、避免列运算导致的全表扫描
21.对于连续数值,使用BETWEEN不用IN:SELECT id FROM t WHERE num BETWEEN 1 AND 5
22.列表数据不要拿全表,要使用分页,每页数量也不要太大
23.把数据、日志、索引放到不同的I/O设备上,增加读取速度。数据量(尺寸)越大,提高I/O越重要。尽量将数据的处理工作放在服务器上,减少网络的开销,如使用存储过程。存储过程是编译、优化过,并且被组织到一个执行规划里,且存储在数据库中的SQL语句(存储过程是数据库服务器端的一段程序),是控制流语言的集合,速度当然快。
24.纵向、横向分割表,减少表的尺寸,如:可以把大数据量的字段拆分表。
25. 针对大量只读查询操作进行优化的方法:
1) 数据量小的数据,可以考虑不存储在数据库中,而是通过程序常量的方式解决。
2) 需要存储在数据库中的数据,可以考虑采用物化视图(索引视图)。当DBA在视图上创建索引时,这个视图就被物化(执行)了,并且结果集被永久地保存在唯一索引中,保存方式与一个有聚簇索引的表的保存方式相同。物化视图减除了为引用视图的查询动态建立结果集的开销,优化人员可以在查询中使用视图索引,而不需要在FROM子句中直接指定视图。
3) 数据存储时可以考虑适当的数据冗余,以减少数据库表之间的链接操作,提高查询效率。
4) 针对数据的特点,采取特定的索引类型。例如,位图索引等。
26.尽量少用游标。游标(Cursor)是处理数据的一种方法,为了查看或者处理结果集中的数据,游标提供了在结果集中一次一行或者多行前进或向后浏览数据的能力,处理大数据量时,效率低下,占用内存大;一般来说,能使用其他方式处理数据时,最好不要使用游标,除非是当你使用while循环,子查询,临时表,表变量,自建函数或其他方式都无法处理某种操作的时候,再考虑使用游标。