第十二章 - MySQL性能优化

第十二章 - MySQL性能优化

优化性能是通过某些高效的方法提高MySQL数据库的性能,其目的是为了使MySQL数据库运行速度更快、占用的磁盘空间更小。性能优化包括优化查询速度、优化更新速度、优化MySQL服务器等。优化MySQL数据库是数据库管理员的必备技能。

在实际工作中,数据的查询优化可以有效地提高MySQL数据库的性能。一个成功的数据库应用系统的开发,在查询优化方面一定会付出资源。对查询优化的处理,不仅会影响到数据库的工作效率,而且会给社会带来较高的效益。
本章将学习优化MySQL服务器、优化数据表、优化查询的方法和技巧。

12.1 优化MySQL服务器

MySQL数据库的用户和数据的量达不到一定的规模,MySQL数据库的性能的好坏很难判断。当有大量用户进行长时间频繁操作地运行,数据库的性能才能体现出来。

当大量用户在同时连接MySQL数据库进行查询、插入和更新的操作时,如果数据库的性能很差,就很可能无法承受如此多用户同时操作,出现数据库系统瘫痪的状况。

优化服务器是MySQL数据库管理的重要方法。优化MySQL服务器可以从两个方面来理解。一个是从硬件方面来进行优化。另一个是从MySQL服务的参数进行优化。

12.1.1 优化服务器硬件

服务器的硬件性能直接决定着MySQL数据库的性能。硬件的性能瓶颈,直接决定MySQL数据库的运行速度和效率。例如,增加内存和提高硬盘的读写速度,这能够提高MySQL数据库的查询、更新的速度。

硬件技术的成熟使得硬件的价格也随之降低。一般的PC机都配置4G内存,一些PC机配置8G内存,甚至有16G内存。因为内存的读写速度比硬盘的读写速度快。可以在内存中为MySQL设置更多的缓冲区,这样可以提高MySQL访问的速度。如果将查询频率很高的记录存储在内存中,那么查询速度就会很快。

对于支持InnoDB存储引擎的表来说,如果条件允许,可以将内存提高到8G,且选用my-innodb-heavy-8G.ini作为MySQL数据库的配置文件。MySQL所在的计算机最好是专用数据库服务器。这样数据库可以完全利用该机器的资源以提高数据的查询速度,优化查询性能。

12.1.2 修改my.ini文件

如果MySQL数据库需要进行大量的查询操作,那么就需要对查询语句进行优化。对于耗费时间的查询语句进行优化,可以提高整体的查询速度。如果连接MySQL数据库用户很多,那么就需要对MySQL服务器进行优化。

MySQL配置文件(my.ini)文件保存了服务器的配置信息,通过修改my.ini文件的配置可以优化服务器,提高性能。

在默认情况下,MySQL数据库索引的缓冲区大小为16M,为得到更好的索引处理性能,可以打开修改my.ini文件,重新设置索引的缓冲区大小,例如可以在[MySQLd]后面加上一行代码设定索引缓冲区为256M。

key_buffer_size=256M  

内存为4GB,则主要的几个参数推荐设置如下:

sort_buffer_size=6M    //查询排序时所能使用的缓冲区大小。
read_buffer_size=4M   //读查询操作所能使用的缓冲区大小。
join_buffer_size=8M   //联合查询操作所能使用的缓冲区大小。
query_cache_size=64M   //查询缓冲区的大小。
max_connections=800    //指定MySQL允许的最大连接进程数。

12.1.3 通过MySQL控制台进行性能优化

数据库管理人员可以使用show status或show variables like语句来查询MySQL数据库的性能参数,然后用set语句对系统变量进行赋值。

1. 查询主要性能参数

(1)利用show status语句查询MySQL数据库的性能语法形式如下:

show status like 'value'; 

使用value参数时常用的几个统计参数。这些常用参数介绍如下。

Connections:连接MySQL服务器的次数;

Uptime:MySQL服务器的上线时间;

Slow_queries:慢查询的次数;

Com_select:查询操作的次数;

Com_insert:插入操作的次数;

Com_update:更新操作的次数。

Com_delete:删除操作的次数。 

(2)利用show variables like语句查询MySQL数据库的性能语法形式如下:

show variables like ‘value’; 

其中,value参数是常用的几个统计参数如下。

key_buffer_size:表示索引缓存的大小。

table_cache:表示同时打开的表的个数。 

query_cache_size:表示查询缓冲区的大小。

Query_cache_type:表示查询缓存区的开启状态。0表示关闭,1表示开启。

Sort_buffer_size:排序缓存区的大小,这个值越大,排序就越快。

Innodb_buffer_pool_size:表示InnoDB类型的表和索引的最大缓存。这个值越大,查询的速度就会越快。但是,这个值太大了也会影响操作系统的性能。 

2. 设置性能指标参数

例如,要设置查询缓存区的系统变量,可先执行以下命令进行观察。

代码和运行结果如下:

mysql> show variables like '%query_cache%'; 

+------------------------------------+------------+
| Variable_name                     | Value     |
+------------------------------------+------------+
| have_query_cache              | YES        |
| query_cache_limit                | 1048576 |
| query_cache_min_res_unit  |  4096     |
| query_cache_size                 | 0           |
| query_cache_type                 | off         |
| query_cache_wlock_invalidate| off       |
+----------------------------------- --+-----------+

12.2 优化查询

MySQL作为Web数据库,每天要接受来自Web的成千上万用户的连接访问。在对数据库频繁操作访问的情况下,数据库的性能好坏越来越成为整个应用的性能瓶颈。

学习使用Explain语句可以对select语句的执行效果进行分析,通过分析提出优化查询的方法;使用analyze table语句可以分析表查询效率等。

使用check语句检查表,使用Optimize Table语句优化表;学习使用repair table语句来修复表的方法。

12.2.1 分析查询语句

在MySQL中,可以使用explain语句和describe语句来分析查询语句。

1. explain语句

应用explain关键字分析查询语句,其语法结构如下:

explain  select statements; 

【例12.1】使用explain语句分析一个查询语句。

mysql> use teaching;
mysql> explain  select *  from  course ;

explain语句输出行的相关信息所代表的意义如下所示:

(1)id:指出在整个查询中select的位置。

(2)select_type:表示查询的类型。参数有几项常用的取值。

 

(3)table:查询的源表名。

(4)partitions:查询的源表是否分区。

(5)type:显示了连接使用了哪种连接类别,是否使用索引,是使用Explain命令分析性能瓶颈的关键项之一。该列中存储很多值,范围从const到all。

(6)possible_keys:指出为了提高查找速度,查询在MySQL中可能用到哪个索引。如果该列是null,则没有相关的索引。

(7)key:显示查询实际使用的键(索引)。

(8)key_len:显示使用的索引字段的长度。

(9)ref:显示使用哪个列或常数与索引一起来查询记录。

(10)rows:显示执行查询时必须检查的行数。

(11)filtered:筛选的结果。

(12)Extra:包含解决查询的附加信息。想要让查询尽可能的快,那么就应该注意extra字段的值为usingfilesort和using temporary的情况。

2. describe语句

在MySQL中应用describe语句来分析查询语句,其使用方法与explain语法是相同的,这两者的分析结果也大体相同。describe可以缩写成desc命令。describe的语法结构如下:

describe select statements; 

【例12.2】利用describe命令分析查询语句。

mysql> describe select * from student; 

图结果中,只是使用了where从句的一个简单查询,没有使用索引进行查询,type为all表示要对表进行全扫描。表格字段rows下为11,说明在执行查询过程中,student表中存在的11条数据都被查询了一遍。

可以想象,在数据存储量小的时候,查询不会有太大影响,当数据库中存储海量的数据时,为搜索一条数据而遍历整个数据表中的所有记录,将会耗费很多时间。

12.2.2 索引对查询速度的影响

在查询过程中使用索引,势必会提高数据库查询效率,应用索引来查询数据库中的内容,可以减少查询的记录数,从而达到查询优化的目的。

下面将通过对使用索引和不使用索引进行对比,来分析查询的优化情况。

【例12.3】分析索引对查询速度的影响,在未使用索引时的查询情况。

mysql> explain select * from student  where  sname= '崔依歌'; 

如果在sname字段上建立一个名为idx_sname的索引。然后应用explain关键字分析执行情况,就可以观察到索引的作用。

代码和运行结果如下:

mysql> create index idx_sname on student(sname);

mysql> explain select * from student where sname ='崔依歌';

12.2.3 使用索引优化查询

在MySQL中,可以通过索引提高查询的速度。为了更充分发挥索引的作用,在应用索引查询时,可以通过关键字或其他方式来对查询进行优化处理。

1. 应用like关键字优化索引查询

【例12.4】利用explain语句执行查询命令,应用like关键字,且匹配字符串中含有百分号“%”符号。

mysql> explain select * from student  where  sname  like '赵%'\G

mysql> explain select * from student where sname like '%江'\G

2. 查询语句中使用or关键字

在MySQL中,查询语句只有包含or关键字时,要求查询的两个字段必须同为索引,如果所搜索的条件中,有一个字段不为索引,则在查询中不会应用索引进行查询。

【例12.5】通过explain来分析应用or关键字查询索引的命令。

mysql> explain  select * from student where sname='赵%' or phone='132%'\G

mysql> explain  select * from student where sname=‘赵%’ or sex=‘男’\G 

从运行结果中可以看出,若两个字段均为索引,故查询被优化,type的值为 index_merge。

而后一种情况,由于sex字段没有被索引,则查询速度不会被优化。Type值为 all,表示进行了全扫描,rows值为11。

3. 查询语句中使用多列索引

多列索引在表的多个字段上创建一个索引。只有查询条件中使用了这些字段中的第一个字段时,索引才会被正常使用。

【例12.6】通过explain来分析应用多列索引的命令。score表中有索引studentno+ courseno,分别用这2个字段进行查询分析。

mysql> explain  select * from score where studentno='18%'\G

mysql> explain  select * from score where courseno='c05%'\G

在应用courseno字段时,索引不能被正常使用,进行的是全表扫描,这就是说索引并未在MySQL优化中起到任何作用。而必须使用字段studentno时,索引才可以被正常使用。

4. 在索引字段上使用函数操作

在建有索引的字段上尽量不要使用函数进行操作,否则会降低查询速度。例如,在一个date类型的字段上使用yeae()函数时,将会使索引不能发挥应有的作用。

【例12.7】在student表的birthdate字段已建立了索引idx_birth,进行的两个查询结果对比一下。

mysql> create index idx_birth on student(birthdate);

mysql> explain select sname from student where month(birthdate)> '2000'\G

mysql> explain select sname from student where birthdate>'2000-12-31'\G

在一个date类型的字段上使用yeae()函数时,将会使索引不能发挥应有的作用。possible_keys值为null,而没有使用yeae()函数时,possible_keys值为idx_birth,证明查询过程中利用了索引idx_birth。但是,由于数据量较小,在指定查询计划时,索引使用的优势显示不明显。

12.2.4 优化多表查询

在MySQL中,很多查询中需要使用子查询。进行子查询时,MySQL需要为内层查询语句的查询结果建立一个临时表。然后外层查询语句再临时表中查询记录。查询完毕后,MySQL需要撤销这些临时表。因此,子查询的速度会受到一定的影响。如果查询的数据量比较大,这种影响就会随之增大。在MySQL中可以使用连接查询来替代子查询。

用户可以通过连接来实现多表查询,在查询过程中,用户将表中的一个或多个共同字段进行连接,定义查询条件,返回统一的查询结果。这通常用来建立数据管理系统的数据表之间的关系。在多表查询中,可以应用子查询来优化多表查询,即在select语句中嵌套其他select语句。

【例12.8】 通过一个实例来说明如何优化多表查询,查看子查询方式和表连接方式的查询分析参数。先执行2个查询语句,再执行查询分析

mysql> select sname ,phone  from student where studentno  
         in  (select studentno from score  where final>98)\G

mysql> select sname,phone from student,score  
where student. studentno =score.studentno and final>98 \G

-- 子查询方式分析
mysql> explain select sname ,phone  
              from student where studentno  
in (select studentno from score  where final>98)\G

-- 表连接方式分析
mysql> explain select sname,phone
             from student,score
       where student. studentno =score. studentno and final>98 \G
(1)从运行结果中可以看出,虽然查询的结果是一样的,但效率却有差别。子查询方式对2个表进行的是全表扫描,子查询本身生成的临时表<subquery2>,也需要扫描。而表连接方式,则仅对score表进行全表扫描,而基于student表的分析,type的值为eq_ref。表明该语句已经将算法进行优化,从而提高了数据表的查询效率,实现了查询优化的效果。

(2)使用子查询可以一次性的完成很多逻辑上需要多个步骤才能完成的SQL操作,同时也可以避免事务或者表锁死,并且写起来也很容易。但是MySQL在执行带有子查询的查询时,需要先为内层子查询语句的查询结果建立一个临时表,然后外层查询语句在临时表中查询记录,查询完毕后再撤销这些临时表。

(3)子查询的速度会受到一定的影响,特别是查询的数据量比较大时,这种影响就会随之增大。因此,尽量使用连接查询来替代子查询,连接查询不需要建立临时表,其速度会比子查询要快。

12.3 优化数据库结构

数据表结构是否合理,需要考虑是否存在冗余、对表的查询和更新的速度、表中字段的数据类型是否合理等多方面的内容。

12.3.1 优化表结构

根据数据库表中数据的使用频率,可以视具体情况对表结构进行适当的增减修改,以此提高相关查询的效率。

1. 将字段很多的表分解成多个表

有些表在设计时设置了很多的字段。这个表中有些字段的使用频率很低。当这个表的数据量很大时,查询数据的速度就会很慢。对于这种字段特别多且有些字段的使用频率很低的表,可以将其分解成多个表。

2. 增加冗余字段

有时,在建立表的时候有意识地增加冗余字段,减少连接查询操作,提高性能。

例如,课程的信息存储在course表中,成绩信息存储在score表中,两表通过课程编号courseno建立关联。对于要查询选修某门课(如数据库编程)的学生,必须从course表中查找课程名称所对应的课程编号courseno,然后根据这个编号去score表中查找该课程成绩。

为减少查询时由于建立连接查询浪费的时间,可以在score表中增加一个冗余字段cname,该字段用来存储课程的名称。这样就不用每次都进行连接操作了。

3. 合理设置表的数据类型和属性

(1)选取适用的字段类型。表中字段的宽度设得尽可能小。

(2)使用enum而不是varchar或char。对诸如“省份”、“性别”、“爱好”、“民族”或“部门”等字段,可以选择enum数据类型。一方面由于这样的字段取值是有限而且固定的,另一方面,MySQL把enum类型当作数值型数据来处理,而数值型数据处理起来的速度要比文本类型快得多。

(3)为每张表设置一个id。为每张数据表都设置id作为其主键,而且最好的是一个int型的主键,并设置自动增量(auto_increment)。

(4)尽量避免定义null。一个提高效率的方法是在可能的情况下,尽量把字段设置为not null,这样在将来执行查询的时候,数据库不用去比较null值。

12.3.2 增加中间表

若有某些查询经常涉及多表中的几个字段,就需要进行多表连接。经常进行连接查询,会降低MySQL数据的查询速度。此时可以视情况将这些字段建立一个中间表,并将原来那几个表的数据插入到中间表中,就可以使用中间表来进行查询和统计。

【例12.9】利用student表、course表和score表的结构,创建中间表stu_score,包含实际中经常要查学生的学号、姓名、课程名和成绩信息。

#查看student表、course表和score表的结构
mysql> describe  student;
mysql> desc course;
mysql> desc  score;

#创建中间表stu_score
mysql> create table stu_score as
    -> select student.studentno,sname,cname,daily, final
    -> from student, course ,score
    -> where student.studentno =score.studentno
    ->    and score.courseno= course.courseno;

【例12.10】统计各科课程的总评成绩的平均分,直接利用stu_score查询。

mysql> select cname, avg(daily*0.2+ final*0.8) avg  
    -> from stu_score group by cname;

12.3.3 优化插入记录的速度

如果MySQL数据表中创建的索引比较多,当需要对表进行插入记录的操作时,就会不断地刷新索引,自动排序数据。如果插入大量数据,索引、唯一性校验都会影响到插入记录的速度。优化插入记录的速度可以从以下几个方面进行处理。

1. 禁用索引

为了解决插入记录时,排序过程会降低插入记录速度的情况,在插入记录之前可以先禁用索引。等到记录都插入完毕后再开启索引。

禁用索引和重新开启索引的命令格式如下:

alter table  tablename  disable keys 
alter table  tablename  enable  keys; 

2. 禁用唯一性检查

插入数据时,MySQL会对插入的记录进行校验。这种校验也会降低插入记录的速度。可以在插入记录之前禁用唯一性检查。等到记录插入完毕后再开启。

禁用唯一性检查和重新开启唯一性检查的命令如下:

set unique_checkS=0; 
set unique_checkS=1;

3. 采用insert语句的优选方式

向数据表中插入多条记录时,有2种insert语句的格式。第一种是一个insert语句只插入一条记录,执行多个insert语句来插入多条记录。第二种是一个insert语句插入多条记录。第二种方式减少了与数据库之间的连接等操作,其速度比第一种方式要快。

在实际操作过程中,若有大量数据需要插入时,建议使用一个insert语句插入多条记录的方式。如果能用load data infile语句,就尽量用load data infile语句。

因为load data infile语句导入数据的速度比insert语句的速度还要快。加载数据时要采用批量加载,尽量减少MySQL服务器对索引的刷新频率。

12.3.4 分析表、检查表和优化表

分析表主要作用是分析关键字的分布。检查表主要作用是检查表是否存在错误。优化表主要作用是消除删除或者更新造成的空间浪费。

1. 利用analyze语句分析表

MySQL中使用analyze table语句来分析表。analyze table语句能够分析InnoDB和MyISAM类型的表。

MySQL的optimizer(优化元件)在优化SQL语句时,首先需要收集相关信息。其中就表的cardinality(散列程度),表示某个索引对应的列包含多少个不同的值。

如果cardinality大大少于数据的实际散列程度,那么索引就基本失效了。

analyze语句的基本语法如下:

analyze table tablename1[,tablename2…]; 

使用analyze table 分析表的过程中,数据库系统会对表加一个只读锁。在分析期间,只能读取表中的记录,不能更新和插入记录。

【例12.11】分析teacher表的运行情况,先使用show index语句来查看索引的散列程度,然后可以使用analyze table进行修复。

mysql> show index from teacher\G;
mysql> analyze table teacher ;
  1. 使用check语句来检查表

MySQL中check table语句能够检查InnoDB和MyISAM类型的表是否存在错误。

数据库经常可能遇到的错误,如数据写入磁盘时发生错误,或是索引没有同步更新,或是数据库未关闭MySQL就停止了,数据库就可能发生错误。此时,可以使用Check Table来检查表,是否有错误。该语句还可以检查视图是否存在错误。

该语句的基本语法如下:

check table tablename1[,tablename2,…][option]; 

例如,检查表student表的运行情况,语句如下。

mysql> Check Table student;

3. 使用optimize语句来优化表

MySQL中optimize table语句对InnoDB和MyISAM类型的表都有效。当表上的数据行被删除时,所占据的磁盘空间并没有立即被回收。另外,对于那些声明为可变长度的数据列,时间长了会使得数据表出现很多碎片,减慢查询效率。

optimize table语句可以消除删除和更新操作而造成的磁盘碎片,用于回收闲置的数据库空间,从而减少空间浪费。使用了optimize table命令后这些空间将被回收,并且对磁盘上的数据行进行重排。optimize table只对MyISAM、BDB和InnoDB表起作用,只能优化表中的varchar、blob和text类型的字段。

对于写比较频繁的表,要定期进行优化,一周或一个月一次,看实际情况而定。

optimize table语句的基本语法如下:

optimize table tablename1[,tablename2,…]; 

通过optimize table语句可以消除删除和更新造成的磁盘碎片,从而减少空间的浪费。optimize table语句在执行过程中也会给表加上只读锁。

例如,利用optilmize table语句优化student表,语句如下。

mysql> optimize table student; 

12.3.5 优化慢查询

Mysql5.7支持将执行比较慢的SQL语句记录下来。

1. 查看相关系统变量,查询系统默认状态

【例12.12】执行下面语句并查看系统设置慢查询的标准结果。long_query_time是用来定义慢于多少秒的才算“慢查询”,系统默认是10秒。

mysql> show variables like 'long%';
mysql> show variables like 'slow%';

2. 设置变量,优化慢查询

【例12.13】将查询时间超过1秒的查询作为慢查询。

mysql> set long_query_time=1;
mysql> show variables like 'long%‘;

3. 检查形成慢查询的原因

(1)了解业务方使用场景,查看查询字段是否没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷);

(2)硬件环境问题。内存不足,网络速度慢,I/O吞吐量小,形成了瓶颈效应;

(3)有没有创建计算列导致查询不优化;查询语句不好,没有优化,是否返回了不必要的数据;查询出的数据量过大(可以采用多次查询,其他的方法降低数据量);

(4)利用explain查看执行计划,是否与预期一致(从锁定记录较少的表开始查询)。

(5)是否形成锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷); 

(6)利用sp_lock、sp_who等参数查看活动的用户,是否存在读写竞争资源。

12.3.6 优化表设计

在MySQL数据库中,为了优化查询,使查询能够更加精炼、高效,在用户设计数据表的同时,也应该考虑一些因素:

(1)在设计数据表时应优先考虑使用特定字段长度,后考虑使用变长字段。适当调整列宽不仅可以减少磁盘空间,同时也可以使数据在进行处理时产生的I/O过程减少。将字段长度设置成其可能应用的最大范围可以充分的优化查询效率。

(2)改善性能的另一项技术是使用optimize table命令处理用户经常操作的表,频繁的操作数据库中的特定表会导致磁盘碎片的增加,这样降低MySQL的效率,故可以应用该命令处理经常操作的数据表,以便于优化访问查询效率。

(3)在考虑改善表性能的同时,要检查用户已经建立的数据表,划分数据的优势在于可以使用户更好的设计数据表,但是过多的表意味着性能降低,故用户应检查这些表,检查这些表是否有可能整合为一个表中,如没有必要整合,在查询过程中,用户可以使连接,如果连接的列采用相同的数据类型和长度。同样可以达到查询优化的作用。

(4) 需要注意的是,数据库表的类型InnoDB或BDB表处理行存储与MyISAM或ISAM表的情况不同。在InnoDB或BDB类型表中使用定长列,并不能提高其性能。

12.4 查询高速缓存

查询缓存存储select查询的文本以及发送给客户端的相应结果。如果随后收到一个相同的查询,服务器从查询缓存中重新得到查询结果,而不再需要解析和执行查询。

12.4.1 检验高速缓存是否开启

当查询解析之前先进行比较操作,例如“select * from score;” 和“Select * From score;”被认为是不同的两个操作,也就意味着查询操作必须是逐字节相同的操作语句串才能够使用高速缓冲;同样的查询字符串有可能认为是不同的。

同样的查询字符串有可能认为是不同的,如:使用不同的数据库、不同的协议版本或者不同的默认字符集的查询,所以高速缓冲将建立不同的查询缓冲。

当一个表被更改,那么使用那个表的所有缓冲查询将不再有效,并从缓冲区中移出。可能更改表的语句包括:insert,update,delete,truncate,alter table,drop table和drop database等命令。

【例12.14】 在MySQL中,应用variables关键字,以通配符形式查看服务器变量。

mysql> show variables like  '%query_cache%';

12.4.2 使用高速缓存

在MySQL中,查询高速缓存的具体语法结构如下:

select sql_cache * from  tablename ; 

【例12.15】 查询student表高速缓存运行中的反应结果。

#开启高速缓存
mysql> set @@global.query_cache_size=1;

#使用查询高速缓存运行结果
mysql> select sql_cache * from teacher;

#未使用查询高速缓存运行结果
mysql> select sql_no_cache * from teacher;

如果经常运行查询高速缓存,将会提高MySQL数据库的性能。一旦表有变化,使用这个表的查询高速缓存将会失效。且将从高速缓存中删除。这样放置查询从旧表中返回无效数据。另外不使用高速缓存查找可以应用sql_no_cache关键字。

12.4.3 优化性能的其他方面

1. limit 1可以增加性能

如果知道查询的结果只有一行时,加上limit 1可以增加性能,MySQL数据库引擎会在找到一条数据后停止搜索,而不是继续往后查找下一条符合记录的数据,从而提高查询的效率。

mysql> select sname,birthdate from student where sname='常杉' limit1; 

2. 尽量避免使用“select * from table”,查询时应明确要查询哪些字段

哪些字段是无关的,从数据库里读出的数据越多,越会增加服务器开销,降低查询的效率。

3. 不要滥用MySQL的类型自动转换功能

应该注意避免在查询中让MySQL进行自动类型转换,因为转换过程也会使索引变得不起作用。

例如,“select studentno ,daily from score where daily >= '60';”数字60就不能写成字符'60',虽然可以输出正确的结果,但会加重MySQL的类型转换,使之的性能下降。

4. 尽量避免在where子句中对字段进行null值判断

null对于大多数数据库都需要特殊处理,MySQL也不例外。不要以为null不需要空间,其实需要额外的空间,并且,在进行比较的时候,程序会更复杂。当然,这里并不是说就不能使用null了,现实情况是很复杂的,依然会有些情况下,需要使用null值。

5. 尽量避免在where子句中使用“!=”或“<>”操作符

MySQL只有在使用<,<=,=,>,>=,between和like的时候才能使用索引。尽量避免where子句对字段进行函数操作。

mysql> select sname from student where year(birthdate)='1999';

-- 可以改为如下形式。

mysql> select sname from student  where birthdate >='1999-12-1’ and birthdate  <= '2002-12-31’; 

6. 尽量避免where子句对字段进行表达式操作

例如:

mysql> select studentno  from score where  score/2=40;

7. 尽量避免使用in或not in操作

对于连续的数值,能用between就不要用in。

mysql>select sname  from score  where score between 60 and 70; 
posted @ 2024-05-14 22:05  WNAG_zw  阅读(3)  评论(0编辑  收藏  举报