因为innodb类型的表是按照主键的顺序保存的,所以将导入的数据按主键的顺序排列,可以有效地提高导入数据的效率。
当前表结构存在唯一性索引
在导入数据前执行SET UNIQUE_CHECKS=0,关闭唯一性校验,在导入结束后执行SET UNIQUE_CHECKS=1,恢复唯一性校验,可以提高导入的效率。
如果应用使用自动提交的方式,建议在导入前执行SET AUTOCOMMIT=0,关闭自动提交,导入结束后再执行SET AUTOCOMMIT=1,打开自动提交,也可以提高导入的效率。
如果需要同时对一张表插入很多行数据时,应该尽量使用多个值的insert语句,这种方式将大大的缩减客户端与数据库之间的连接、关闭等消耗。使得效率比分开执行的单个insert语句块。
在事务中进行数据插入。
数据有序插入。
两种排序方式:
1)第一种是通过对返回数据进行排序,也就是通常说的filesort排序,所有不是通过索引直接返回排序结果的排序都叫FileSort排序。
2)第二种通过有序索引顺序扫描直接返回有序数据,这种情况即为using index,不需要额外排序,操作效率高。
*多种排列规则(同时有升序、降序),第一排序后的索引失效。
*排序的顺序和索引的顺序不一致,第一排序后的索引失效。
#注意
了解了MySQL的排序方式,优化目标就清晰了:尽量减少额外的排序,通过索引直接返回有序数据。where条件和order by 使用相同的索引,并且order by 的顺序和索引顺序相同,并且order by 的字段都是升序,或者都是降序。否则肯定需要额外的排序,这样就会出现Filesort。
通过创建合适的索引,能够减少Filesort的出现,但是在某些情况下,条件限制不能让Filesort消失,那就需要加快Filesort的排序操作。对于Filesort,MySQL有两种排序算法:
1)两次扫描算法:MySQL4.1之前,使用该方式排序。首先根据条件取出排序字段和行指针信息,然后再排序区sortbuffer中排序,如果sortbuffer不够,则在临时表temporary table中存储排序结果。完成排序之后,再根据行指针读取记录,该操作可能会导致大量随机I/O操作。
2)一次扫描算法:一次性取出满足条件的所有字段,然后再排序区sort buffer中排序后直接输出结果集。排序是内存开销较大,但是排序效率比两次扫描算法要高。
MySQL通过比较系统变量max_length_for_sort_data的大小和Query语句取出的字段总大小,来判定是用哪种排序算法,如果max_length_for_sort_data更大,那么使用第二种优化之后的算法,否则使用第一种。
可以适当提高sort_buffer_size和max_length_for_sort_data系统变量,来增大排序区的大小,提高排序效率。
由于group by实际上也同样会进行排序操作,而且与order by相比,group by主要致死多了排序之后的分组操作。当然,如果在分组的时候还是用了其他的一些聚合函数,那么还需要一些聚合函数的计算。所以,在group by的实现过程中,与order by一样也可以利用到索引。
MySQL4.1版本之后,开始支持SQL的子查询。这个技术可以使用SELECT语句来创建一个单列的查询结果,然后把这个结果作为过滤条件用在另一个查询中。使用子查询可以一次性的完成很多逻辑上需要多个步骤才能完成的SQL操作,同时也可以避免事务或者表锁死,并且写起来也很容易。但是,有些情况下,子查询是可以被更高效的连接(JOIN)替代。
对于包含OR的查询子句,如果要利用索引,则OR之间的每个条件列都必须用到索引,而且不能使用复合索引;如果没有索引,则应该考虑增加索引。
每个列必须有单列索引,不能使用复合索引,否则索引失效。
我们来比较以下重要指标,发现主要差别是type和ref这两项
type显示的是访问类型,是较为重要的一个指标,结果值从好到坏依次是:
system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subqeury>range>index>ALL
查询起始位置越大,速度越慢。
在索引上完成排序分页操作,最后根据主键关联回原表查询所需要的其他列内容。
该方案适用于主键自增的表,可以吧limit查询转换成某个位置的查询。
必须是主键自增的列,并且主键还不能出现断层。
SQL提示,是优化数据库的一个重要手段,简单来说,就是在SQL语句中加入一些人为的提示来达到优化操作的目的。
在查询语句中表名的后面,添加use index来提供MySQL去参考的索引列表,就可以让MySQL不再考虑其他可用的索引。
如果用户只是单纯的想让MySQL忽略一个或者多个索引,则可以使用ignore index作为hint。
为强制MySQL使用一个特定的索引,可在查询中使用force index作为hint。