MySQL—浅谈优化

索引

通过使用索引,可以大大提高SQL的性能。
数据库中索引有如下几类:

  • B+树索引 :MyISAM和InnoDB引擎默认使用的索引,最传统的索引。底层使用了B+树结构,查询效率和树高度成正比,树的高度在数据库中就代表了I/O次数。B+树索引又可以分为聚集和非聚集索引。

    • 聚集索引:聚集索引的数据页存放的是完整的记录,B+树的叶子存放的是数据。
    • 非聚集索引:B+树的叶子存放的是记录的主键,所以使用非聚集索引只能查询还需要使用聚集索引插叙数据。
  • 哈希索引 :和数据量大小没有关系,查询复杂度为O(1),因此是比B+树索引更加有效的查询方式。只有Memory/HEAP引擎支持,InnoDB支持自适应的哈希索引。自适应的哈希索引由引擎自己完成的,用户不能创建。哈希索引索引不是对全表数据进行索引,而是系统认为的热点页的数据创建索引。自适应的哈希索引是在内存中创建的,所以不能持久化。

  • 全文索引:用于实现关键字的查询,是MyISAM的特殊索引,可以在字符串列上使用全文索引,但是InnoDB不支持这种索引。

  • RTree索引:空间索引,是MyISAM的特殊索引,主要用于地理空间数据类型,使用比较少。

PS:MyISAM的索引是属于非聚集索引的,因为存储结构决定了数据和索引分开。InnoDB的主键索引是聚集索引,非主键索引就是非聚集索引。

索引使用的场合

 1. 使用匹配全值,对所有列都指定具体值,也就是对索引中的所有列都有等值匹配的条件。例如:select * from xxx where colums1=value1 and colums2=value2.
 2. 匹配值的范围查询,对索引值能够范围查找。例如:select * from xxx where colums1>=value1 and colums23. 匹配最左前缀。仅仅使用索引中的最左列查找,比如col1+col2+col3能被col1,clo1+col2,col1+col2+col3的查询使用到,也称最左匹配原则。
 4. 仅仅对索引进行查询,也就是查询的列都在索引字段里面。
 5. 匹配列前缀,仅仅使用索引中的第一项,并且只包含索引第一列的开头一部分进行查找。
 6. 实现索引部分精确匹配,其他部分范围匹配。例如:select * from xxx where index_col=value and other_cols>=xxx。
 7. 如果列名的索引,那么使用列名=null就会用到索引。

存在索引但是不能使用索引的场合

  1. 以%开头的LIKE查询不能使用索引。
  2. 数据类型隐式转换时,特别是使用字符串类型时,在where后面一定要加上单引号
  3. 复合索引情况下,不满足最左原则是不使用复合索引的。
  4. 如果使用索引比搜索全表来的慢,不会使用索引。
  5. 使用or分割开的条件,如果or前面有索引,后面没索引则不会使用索引。

常用SQL优化

大批量插入

对于大批量插入,MyISAM关闭唯一索引的更新。插入数据以后再打开索引更新,也就是先插入数据然后再对数据检查。
对于InnoDB:
1.应该将插入的数据按照主键顺寻排列好
2.导入数据之前关闭数据校验,导入数据结束以后再开启
3.导入数据前关闭自动提交,导入数据以后再开启自动提交

对于一般的INSERT语句,应该使用多个值表的语句。例如:insert into table value (xxx),(xxx),(xxx)。。。。。。

ORDER BY的优化

MySQL中有两种排序方法,第一种直接通过有序的索引顺序返回有序的数据,这种方式无需额外的排序,效率高。第二种是Filesort,就是对返回的结果进行一次排序,所有不是通过索引直接返回结果的都是Filesort。因此,我们的优化目标就是减少Filesort,而通过索引直接返回有序结果。所以,在SQL语句中,WHERE条件和ORDERBY要使用相同的索引,并且ORDERBY的顺序和索引相同,并且ORDERBY的顺序都是降序或者升序,否则肯定需要使用Filesort。

GROUP BY的优化

默认情况下,MySQL会对于GROUP BY中的字段进行排序,如果我们需要这种排序,那么对MySQL的实际执行没有影响。但是如果我们并不需要对结果进行排序,那么我们可以指定ORDER BY NULL禁止GROUP BY带来的排序

嵌套语句优化

SQL的子查询可以使用SELECT创建单列的查询结果,然后把这个结果作为过滤条件用在另外一个查询中,虽然子查询好处多多,但是有时候使用连接JOIN会有更好的效率,那是因为使用JOIN不需要在内存中创建临时表来完成查询工作;而子查询会在内存中建立一个临时表,这回降低查询效率。

OR优化

对于含有OR的查询语句,只要存在一个没有索引的列,那么就会进行全表查询而放弃使用索引。因此,如果要使用索引,则OR之间的每一个条件列都要用到索引,没有索引就串讲索引。

分页查询的优化

使用分页查询语句时,例如”limit 10000,20”,此时数据库会查询前面10020条记录,而我们只需要后20条记录,那么前10000条记录的查询是无用,这就会造成不必要的性能浪费。
优化思路一:先在索引上完成排序分页的操作,然会根据主键关联回原表查询需要的其他内容。
优化思路二:把LIMIT查询转化为某一个位置的查询。

应用优化

除了对数据库本身优化以外,我们还可以对使用数据的外部应用进行优化。

  • 使用数据库连接池:数据库连接池和线程池类似,目的是减少重复连接-断开操作的开销,常见的数据库连接池有:C3P0,DBCP还有阿里的druid。
  • 使用查询缓存:第一次查询数据库时,将数据内容进行缓存,下一次做同样的查询就直接从缓存中取数据即可,不需要再次访问数据库。常见的数据库缓存系统有:Redis,Memcached。
  • 负载均衡:利用均衡算法,将固定的负载量分布到不同服务器,以此减轻单台服务器的负载,达到优化的目的。具体方式如:使用MySQL的主从复制分流查询操作,或者使用分布式数据库架构,其具体实现可以使用MySQL的CLUSTER功能。

总结:主要讲了MySQL常见的优化除了使用索引、SQL语句优化、外部引用优化,除此以外MySQL还有许多优化的办法,如优化MySQL Server,优化磁盘等。

你可能感兴趣的:(数据库,mysql,数据库)