SQL语句优化

大量插入数据时SQL语句的优化

1)对于MyISAM类型的表,可以通过以下方式快速地导入大量数据:

这两个命令用来打开或者关闭MyISAM表非唯一索引的更新。在导入大量的数据到一个非空的MyISAM表是,通过设置这两个命令,可以提高导入的效率。对于导入大量数据到一个空的MyISAM表,默认就是先导入数据然后才创建索引的,所以不用进行设置。

er对于InnoDB类型的表,这种方式并不能提高导入数据的效率。

2)对于InnoDB类型的表,可以用以下几种方法提高导入的效率:

  1. 因为InnoDB类型的表是按照组件的顺序保存的,所以将导入的数据按照主键的顺序排列,可以有效地提高导入数据的效率。如果InnoDB表没有主键,那么系统会默认创建一个内部列作为主键,所以如果可以给表创建一个组件,将可以利用这个优势提高导入数据的优势
  2. 在导入数据钱执行SET UNIQUE_CHECKS=0,关闭唯一性校验,在导入结束后执行SET UNIQUE_CHECKS=1,回复唯一性校验,可以提高导入的效率。
  3. 如果应用使用自动提交的方式,建议在导入前执行SET AUTOCOMMIT=0,关闭自动提交,导入结束后再执行SET AUTOCOMMIT=1,打开自动提交,也可以提高导入的效率。



INSERT语句的优化

1)如果同时从一个客户插入很多行,使用多个值表的INSERT语句。这比使用分开的INSERT语句快(在一些情况中几倍)

2)如果从不同客户插入很多行,能通过使用INSERT DELAYED语句得到更高的速度。DELAYED的含义是让INSERT语句马上执行,其实数据都被放在内存的队列中,并没有真正写入磁盘;这比每条语句分别插入要快的多;LOW_PRIORITY刚好相反,在所有其他用户对表的读写完后才进行插入。

3)将索引文件和数据文件分别放在不同的磁盘上存放(利用建表中的选项)

4)如果进行批量插入,可以证件bult_insert_buffer_size变量值的方法来提高速度,但是,这只能针对MyISAM类型的表使用。

5)当从一个文本文件装载一个表时,使用LOAD DATA INFILE,这通常比使用很多INSERT语句快20倍

6)根据应用情况使用REPLACE语句代替INSERT

7)根据应用情况使用IGNORE关键字忽略重复记录


GROUP BY语句的优化

默认情况下,MySQL排序所有的GROUP BY col1,col2....,查询的方法如同在查询中指定ORDER BY col1,col2...。如果显式包括一个包含相同的列的ORDER BY语句,MySQL可以毫不减速地对它进行优化,尽管仍然进行排序。


如果查询包括GROUP BY但你想要避免排序结果的损耗,你可以指定ORDER BY NULL禁止排序,例如:


ORDER BY语句优化

在某些情况下,MySQL可以使用一个索引来满足ORDER BY子句,而不需要额外的排序。WHERE条件和ORDER BY使用相同的索引,并且ORDER BY的顺序和索引顺序相同,并且ORDER BY的字段都是升序或者降序。


例如,下列的SQL可以使用索引。

但是以下的情况不使用索引:



JOIN语句的优化

MySQL4.1开始支持SQL的子查询,这个计数可以使用SELECT语句来创建一个单列的查询结果,然后把这个结果作为过滤条件用在另一个查询中。使用子查询可以一次性完成很多逻辑上需要多个步骤才能完成的SQL操作,同时也可以避免事务或者表锁死,并且写起来也很容易。但是,有些情况下,子查询可以被更有效的连接JOIN替代。


架设我们要将所有没有订单记录的用户取出来,可以使用下面这个查看来完成:


如果使用连接JOIN来完成这个查询工作速度将会快很多。尤其当salesinfo表中对CustomerID建有索引的话,性能将会更好,查询如下:

SQL语句优化_第1张图片

连接JOIN之所以更有效率一些,是因为MySQL不需要在内存中创建临时表来完成这个逻辑上需要两个步骤的查询工作。


INSERT、UPDATE、DELETE顺序的优化

MySQL还允许改变语句调度的优先级,它可以使来自多个客户端的查询更好地协作,这样单个客户端就不会由于锁定而等待很长时间。改变优先级还可以确保特定类型的查询被处理得很快。


我们首先应该确定应用的类型,判断应用是以查询为主还是以更新为主,是确保查询效率还是确保更新的效率,决定是查询优先还是更新优先。


下面我们提到的改变调度策略的方法主要是针对MyISAM存储引擎的,对于InnoDB存储引擎,语句的执行是由获得行锁的顺序决定的。


MySQL的默认的调度策略可以总结如下:

  • 写入操作优先于读取操作
  • 对某张数据表的写入操作某一时刻只能发生一次,写入请求按照它们到达的次序来处理
  • 对某张数据表的多个读取操作可以同时进行

MySQL提供了几个语句调节符,允许修改它的调度策略:

  • LOW_PRIORITY关键字应用于DELETE、INSERT、LOAD DATA、REPLACE和UPDATE。
  • HIGH_PRIORITY关键字应用于SELECT和INSERT语句
  • DELAYED关键字应用于INSERT金额REPLACE语句

如果写入操作是一个LOW_PRIORITY(低优先级)请求,那么系统就不会认为它的优先级高于读取操作。在这种情况下,如果写入者在等待的时候,第二个读取者到达了,那么就允许第二个读取者查到写入者之前。只有在没有其他读取者的时候,才允许写入者开始操作。这种调度修改可能存在LOW_PRIORITY写入操作永远被阻塞的情况


SELECT查询的HIGH_PRIORITY(高优先级)关键字也类似。它允许SELECT插入正在等待的写入操作之前,即使在正常情况下写入操作的优先级更高。另外一种影响是,高优先级的SELECT在正常SELECT语句之前执行,因为这些语句会被写入操作阻塞。


如果你希望所有支持LOW_PRIORITY选项的语句都默认地按照低优先级来处理,那么请使用--low-priority-updates选项来启动服务器。通过使用INSERT HIGH_PRIORITY来吧INSERT语句提高到正常的写入优先级,可以消除该选项对单个INSERT语句的影响。










你可能感兴趣的:(mysql)