MYSQL数据库调优教程

MySQL数据库初学者全攻略教程 MySQL是一种流行的开源关系型数据库管理系统(RDBMS),最初由瑞典的MySQL AB公司开发。由于其高性能、高可靠性和易用性,MySQL成为了互联网上最受欢迎的数据库之一。它使用结构化查询语言(SQL)进行数据库管理,遵循客户/服务器模型,能够处理大量数据的存储和管理任务。MySQL的配置文件通常位于(在某些Linux发行版中可能是)或者目录下。在这个配置文件中,可以设置MySQL的各种参数来优化其性能和安全性。配置文件主要包含以下几个部分:[mysqld] 阅读详情

前言

 

最近帮公司优化数据库,凭着之前所学,一步一步地将学习知识用于实践,总算是将速度蹭上去了,一个原本要执行1分多钟的查询现在只需要3秒。

现把自己所学所思及所用加以总结,一方面为自己巩固知识,另一方面也给广大同学以一点点参考。


本套教程共十三讲。


在这系列的教程中,你将会学到

1.     如何一步步地优化数据库

2.     如何把索引的作用发挥的淋漓尽致

3.     如何解决Mysql在like’%xxx%’模糊查询的情况下不使用索引

4.     如何设计一张优质的表

5.     如何写出高质量的sql语句

6.     数据库优化的其他方法

 

首先,让我们从发现慢查询开始。


一、           发现慢查询


如何从一个大项目中,迅速的定位执行速度慢的语句,这是本章节将要解决的问题。

1.      慢查询的定义

怎样的查询才算是慢查询,有没有一个量化的标准呢?

慢查询定义

       慢查询是指执行时间超过慢查询时间的sql语句。

查看慢查询时间的方法

[plain]  view plain copy
  1. show variables like 'long_query_time';  

可以显示当前慢查询时间。MySql默认慢查询时间为10秒


可以通过如下语句对慢查询的定义进行修改

[plain]  view plain copy
  1. set global long_query_time=1;  


(如果你的mysql设置了缓存,那么需要重新进入命令行窗口才会查出变化)

需要注意的是,这个语句特意在变量前加上了global,表明这次的设置是对整个Mysql有效的,而默认情况下变量前的修饰符是session(会话),也就是只对当前窗口有效。


这一讲只是开个头,下一讲,我们会为慢查询的发生准备数据,即创建一张大表。


一、           发现慢查询


上一讲我们谈论了慢查询的定义,这一讲我们来创建一张大表,为慢查询做数据准备。


2.      慢查询数据准备


要想发现慢查询,首先要使慢查询发生。在一张普通数量级的表格中是不能发生慢查询的,除非你对于慢查询的定义时一个毫秒。因此我们必须手动创建一张大数量级的表,这里选择创建一张40万数量级的表(同学们也可以创建百万级的,如果你们的电脑很厉害。但是一般情况下,十万级的数据就可以看出慢查询了)。

1)    创建数据库

[plain]  view plain copy
  1. Create database bigTable default character set GBK;  

2)    创建表

#部门表#


[plain]  view plain copy
  1. CREATE TABLE dept(  
  2. id int unsigned primary key auto_increment,  
  3. deptno MEDIUMINT   UNSIGNED  NOT NULL  DEFAULT 0,   
  4. dname VARCHAR(20)  NOT NULL  DEFAULT "",  
  5. loc VARCHAR(13) NOT NULL DEFAULT ""  
  6. ) ENGINE=INNODB DEFAULT CHARSET=GBK ;  


#雇员表#

[plain]  view plain copy
  1. CREATE TABLE emp  
  2. (  
  3. id int unsigned primary key auto_increment,  
  4. empno  MEDIUMINT UNSIGNED  NOT NULL  DEFAULT 0, /*编号*/  
  5. ename VARCHAR(20) NOT NULL DEFAULT "", /*名字*/  
  6. job VARCHAR(9) NOT NULL DEFAULT "",/*工作*/  
  7. mgr MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,/*上级编号*/  
  8. hiredate DATE NOT NULL,/*入职时间*/  
  9. sal DECIMAL(7,2)  NOT NULL,/*薪水*/  
  10. comm DECIMAL(7,2) NOT NULL,/*红利*/  
  11. deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0 /*部门编号*/  
  12. )ENGINE=INNODB DEFAULT CHARSET=GBK ;  


3)    创建函数

函数用于随机产生数据,保证每条数据都不同

#函数1 创建#

#创建函数. 用于随机产生字符串。该函数接收一个整数


[plain]  view plain copy
  1. delimiter $$#定义一个新的命令结束符合  
  2. create function rand_string(n INT)   
  3. returns varchar(255) #该函数会返回一个字符串  
  4. begin   
  5. #chars_str定义一个变量 chars_str,类型是 varchar(100),默认值'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';  
  6.  declare chars_str varchar(100) default  
  7.    'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';  
  8.  declare return_str varchar(255) default '';  
  9.  declare i int default 0;  
  10.  while i < n do   
  11.    set return_str =concat(return_str,substring(chars_str,floor(1+rand()*52),1));  
  12.    set i = i + 1;  
  13.    end while;  
  14.   return return_str;  
  15.   end $$  


#函数2创建#

#用于随机产生部门编号

[plain]  view plain copy
  1. create function rand_num( )  
  2. returns int(5)  
  3. begin   
  4.  declare i int default 0;  
  5.  set i = floor(10+rand()*500);  
  6. return i;  
  7.   end $$  


4)    创建存储过程

 

#存储过程一#

#该存储过程用于往emp表中插入大量数据

[plain]  view plain copy
  1. create procedure insert_emp(in start int(10),in max_num int(10))  
  2. begin  
  3. declare i int default 0;   
  4. #set autocommit =0 把autocommit设置成0  
  5.  set autocommit = 0;    
  6.  repeat  
  7.  set i = i + 1;  
  8.  insert into emp (empno, ename ,job ,mgr ,hiredate ,sal ,comm ,deptno ) values ((start+i) ,rand_string(6),'SALESMAN',0001,curdate(),2000,400,rand_num());  
  9.   until i = max_num  
  10.  end repeat;  
  11.    commit;  
  12.  end $$  


执行存储过程,往emp表添加40万条数据

[plain]  view plain copy
  1. call insert_emp(100001,400000);  

查询,发现Emp表插入了40万条记录



#存储过程二#

#往dept表添加随机数据

[plain]  view plain copy
  1. create procedure insert_dept(in start int(10),in max_num int(10))  
  2. begin  
  3. declare i int default 0;   
  4.  set autocommit = 0;    
  5.  repeat  
  6.  set i = i + 1;  
  7.  insert into dept (deptno ,dname,loc  ) values ((start+i) ,rand_string(10),rand_string(8));  
  8.   until i = max_num  
  9.  end repeat;  
  10.    commit;  
  11.  end $$  


执行存储过程二

[plain]  view plain copy
  1. delimiter ;  
  2. call insert_dept(100,10);  


至此,数据准备完成。我们创建了大表emp。


下一讲,我们将利用已创建的大表去发现慢查询,并试着把慢查询记录到日志中。

上一讲我们为慢查询的发生做了数据准备,这一讲就让我们来发现慢查询,同时把它记录到文件中。

3.      记录慢查询


此时我们已经有让慢查询发生的成本了。执行以下语句,你就知道什么叫慢!查!询!

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. select empno from emp where ename='';  


一个很明显找不到结果的查询语句居然也执行了近3秒钟。

这时候,作为DBA就应该把这个sql语句记录下来,是记在记事本还是写在笔记本呢?不用想太多了,不用你自己记,Mysql提供了慢查询日志功能,自动帮你记录慢查询的语句。

1)    把慢查询的sql记录到日志中

首先你要打开慢查询日志文件记录器

使用

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. show variables like 'slow%';  

你会发现默认情况下慢查询日志记录器关闭的

使用

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. set global slow_query_log=ON;  

打开之



此时你会发现mysql安装目录下的data文件夹中出现了以你本机名命名的日志文件


此时再执行慢查询操作


打开日志文件发现出现记录


以后只需要定期检查日志文件就可以找到慢查询语句了


注意:

在找到慢查询语句后,要通过反复使用select语句确认慢查询,注意只能使用select语句,就算是原来语句为delete或者update等,也要用select代替,因为只有select不会弄脏数据库


2)    另一种发现慢查询语句的方法

要是你使用Hibernate进行J2ee开发,可以使用一下方式。

在页面中进行操作,当发现某个操作的响应较慢时,查看Eclipse控制台的Hibernate输出sql语句,此语句即为慢查询语句。


本章结束,下一章我们将讲解如何使用mysql的性能分析命令Explain。

上一章我们将了如何发现慢查询并把语句记录到日志中,那么在发现慢查询后,要怎样才能知道语句的问题发生在哪里。本章将介绍怎样使用Mysql提供的数据库性能分析命令,对sql语句进行分析。


二、数据库性能分析Explain命令


Explain的作用是生成一个QEP(查询执行计划),可以帮助我们在不真正执行某个sql语句时,就看到mysql怎样执行,这样方便我们去分析sql指令的好坏。

执行如下语句

[plain]  view plain copy
  1. Explain select * from emp where empno = 3333\G  

对于返回的信息,我们主要关心一下几个

1)    Type

ALL全表扫描,通常是不好的,其他的如index、range、const、ref、system则是较好的

2)    Possible_keys

       可能被用到的索引

3)    Key

       查询过程中实际使用的索引,当为null时表示没有使用索引,通常是不好的

4)    key_len

索引字段最大可能使用的长度,也叫索引基数。索引基数越大,表明可能查找的行数越多,查询效率越慢。

5)    Rows

MySQL 估计的需要扫描的行数。只是一个估计。越多表明查找的行数越多,自然越慢。

6)    Extra

显示上述信息之外的其它信息,非常重要。其主要有一下返回结果。

       Usingindex

表明此查询使用了覆盖索引(CoveringIndex),即通过索引就能返回结果,无需访问表。(覆盖索引是一种非常优秀的索引,其使用见http://blog.youkuaiyun.com/hzy38324/article/details/44857721)

若没显示"Usingindex"表示读取了表数据。

       Usingindex condition

可能会使用索引

       Usingwhere

表示 MySQL 服务器先读取整行数据,再检查此行是否符合 where 句的条件,符合就留下,不符合便丢弃。效率较慢。

       Usingfilesort

表示Mysql会按查询所需的顺序对结果进行排序,这时就会出现 Usingfilesort 。排序自然会增加查询时间,导致效率变慢。解决方法是利用索引进行排序。若查询所需的排序与使用的索引的排序一致,因为索引是已排序的,因此按索引的顺序读取结果返回,此时就不会出现Using filesort。

       关于“Using index” 和 “Using index condition”的区别,笔者参考了一下stackoverflow上的一篇文章

http://stackoverflow.com/questions/1687548/mysql-explain-using-index-vs-using-index-condition

里面是这么解释的


简单的说

Using index就是一定使用索引,这种索引成为覆盖索引,Using index condition则是在必要的时候才使用索引

怎样才能让Usingindex condition变成Using index,答案自然是创建一个覆盖索引,同样,笔者将会在之后章节介绍覆盖索引如何创建。


本章结束,下一章我们将全面讲解性能优化的利器——索引。

三、           索引


上一章我们学习了使用explain来生成一个查询执行计划(QEP),从而发现语句存在的问题。在explain返回的结果中,有三个是和索引有关的(possible key、key、extra),可见索引在改善查询效率上的显著地位。

这一章,我们将全方位讲解如何使用索引来优化我们的数据库。

1.      索引的作用

索引的原理是利用特殊的查找算法(如二叉树算法),限制访问的行数,提高访问效率。

另外,索引还可以高效地在表之间建立连接操作,高效的对结果进行排序等等

2.      基本索引种类及创建

索引可以分为主键索引、普通索引、唯一索引和全文索引。

1)    主键索引

当一张表,把某个列设为主键的时候,则该列就是主键索引

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. create table aaa  
  2. (id int unsigned primary key auto_increment ,  
  3. name varchar(32) not null defaul ‘’);  

这是id 列就是主键索引.

如果你创建表时,没有指定主键索引,也可以在创建表后再添加

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. alter table 表名 add primary key (列名);  

2)    普通索引

一般来说,普通索引的创建,是先创建表,然后在创建普通索引

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. create index 索引名 on 表 (列名1,列名2);  

当括号中的列不止一个时,我们称之为多列索引,多列索引在一定情况下可以进化为覆盖索引(后面会介绍)。

这里我们通过在emp表中创建普通索引来见识一下索引的威力。

在未创建索引前

我们执行以下语句

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. select count(1) from emp where ename like 'yu%';  


接着我们创建索引

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. create index index_ename on emp(ename);  


再次执行

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. select count(1) from emp where ename like 'yu%';  


不可思议!

索引的威力可见一斑!

当然索引是有开销的

这是我在未创建索引时mysql安装目录下data/bigtable/emp.ibd文件的大小,对于innodb引擎的表来说,ibd文件存放了表的数据和索引。


在我创建了索引之后


显然,索引会占用主机的空间,这也称作索引的开销。

3)    唯一索引

当表的某列被指定为unique约束时,这列就是一个唯一索引
[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. create table ddd(id int primary key auto_increment , name varchar(32) unique);  

这时, name 列就是一个唯一索引

在创建表后,再去创建唯一索引

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. create unique index 索引名  on 表名 (列表..);  
unique字段可以为NULL,并可以有多NULL,即Null!=Null。但是如果是具体内容,则不能重复

4)    全文索引

全文索引,只对MyISAM引擎有用。主要是针对对文件,文本的检索, 比如文章或者段落,.

它会把某个数据表的某个数据列出现过的所有单词生成一份清单

全文索引的创建

在创建表时创建

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. CREATE TABLE articles (  
  2.        id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,  
  3.        title VARCHAR(200),  
  4.        body TEXT,  
  5.        FULLTEXT (title,body)  
  6.      )engine=myisam charset utf8;  

或者在创建表后添加

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. ALTER TABLE articles ADD FULLTEXT (title,body);  

全文索引正确的用法是:

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. select * from articles where match(title,body) against(‘要搜索的单词’);  

另外,mysql自己提供的fulltext针对英文生效,想要搜索中文需要使用sphinx全文检索引擎或者使用加强版的模糊查询。

注意:

全文索引不完全等同于模糊查询

比如title字段有这么个数据’abcd20088ccaa’,使用模糊查询select * from articleswhere title like’%2008%’可以查找到,而使用全文检索select * from articleswhere match(title) against(‘2008’);是检索不到的,因为2008不是一个单词 !


本讲结束,下一讲将讲解索引的相关操作。

三、           索引


3.      索引的相关操作

上一讲我们介绍了索引的作用和种类,这一讲我们谈谈索引的相关操作!

1)    添加索引

前面已经有所介绍,这里总结一下

添加主键索引

[plain]  view plain copy
  1. create table aaa  
  2. (id int unsigned primary key auto_increment ,  
  3. name varchar(32) not null defaul ‘’);  
  4.   
  5. alter table 表名 add primary key (列名);  

添加普通索引

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. create index 索引名 on 表 (列名1,列名2);  

添加唯一索引

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. create table ddd(id int primary key auto_increment , name varchar(32) unique);  
  2.   
  3. create unique index 索引名  on 表名 (列表..);  

添加全文索引

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. CREATE TABLE articles (  
  2.        id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,  
  3.        title VARCHAR(200),  
  4.        body TEXT,  
  5.        FULLTEXT (title,body)  
  6.      )engine=myisam charset utf8;  
  7.   
  8. ALTER TABLE articles ADD FULLTEXT (title,body);  

2)    查询索引

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. show index from emp\G  


3)    删除索引

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. drop index 索引名称 on 表名;  

4)    修改索引

先删除,再创建



本讲结束,下一讲将给大家聊聊索引的代价。

4.      索引的代价

前面几讲介绍了索引在提高性能方面的威力以及如何使用索引,但是索引也是有开销的

1)    占用磁盘空间

如前面所述,索引是有开销的,表现在添加索引后.ibd文件(innodb引擎)或者.myi文件(myisam引擎)会变大。


2)    导致dml操作速度变慢

添加索引后之所以会快,是因为表依据索引对数据按某种算法(二叉树等)进行排序,所以删除、增加、插入后二叉树要重新排序,导致执行效率降低。

 

此时要看自己的数据库是dml语句执行的多还是dql语句执行的多

使用以下语句可以查询

 

查询一共执行了多少次select

[plain]  view plain copy
  1. show  status like ‘com_select’  

查询一共执行了多少次insert

[plain]  view plain copy
  1. show status like ‘com_insert’  

以此类推

 

一般来说,dql语句操作比dml语句要多得多!接近9:1

 

既然索引有利有弊,那么怎样人为地控制索引的使用呢?

强制不使用索引

[plain]  view plain copy
  1. select xxx from table ignore index(index_xxx)  

强制使用索引

[plain]  view plain copy
  1. select * from table force index(index_xxx)  


本讲结束,下一讲来讲一下如何正确地使用索引。

5.      什么情况下不要使用索引


既然索引是有代价的,那么就不要在不应该使用索引的情况下去使用它。

1)    数据唯一性差的字段不要使用索引

比如性别,只有两种可能数据。意味着索引的二叉树级别少,多是平级。这样的二叉树查找无异于全表扫描。

2)    频繁更新的字段不要使用索引

比如logincount登录次数,频繁变化导致索引也频繁变化,增大数据库工作量,降低效率。

3)    字段不在where语句出现时不要添加索引

只有在where语句出现,mysql才会去使用索引

4)    数据量少的表不要使用索引

使用了改善也不大

 

另外。如果mysql估计使用全表扫描要比使用索引快,则不会使用索引。



本讲结束,下一讲聊聊为什么有时候建了索引也不会被Mysql使用。

6.      添加了索引但不被使用的几种常见可能


上一讲聊了什么时候不要使用索引,但有时候使用了也不见得会被使用。

下面是几种添加了索引但不被使用的情况


1)    多列索引查询条件没有使用最左边的字段

对于创建的多列索引,如果查询条件没有使用最左边的列,索引就不会被使用。

多列索引:一个索引对应多个列

比如

我创建了这么个多列索引

[plain]  view plain copy
  1. create index index_deptno_loc on dept (deptno,loc);  

如果where语句中有deptno则会使用索引,否则不使用

如下


2)    如果条件中有or

只要条件中有一个字段没有添加索引,则不会使用索引

 

3)    类型不对应

比方说,如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。否则不使用索引

 

4)    mysql优化器的决定

如果mysql估计使用全表扫描要比使用索引快,则不使用索引

 

最后一点,也是笔者感受最深的一点


5)    like‘%aaa’不会使用到索引

只要模糊查询的模糊值在字符串前面,则不会使用索引‘%aaa’和‘_aaa’都不会!

如下



应该说这是Mysql给程序员们开的一个玩笑。要是我的表数据量很大,而且又需要使用like’%%’这样的模糊查询来检索时,该怎么办??

7.      解决like’%str’不使用模糊查询的4种方法


上一讲最后说了,只要模糊查询的模糊值在字符串前面,则不会使用索引,‘%aaa’和‘_aaa’都不会!

如下


应该说这是Mysql给程序员们开的一个玩笑。要是我的表数据量很大,而且又需要使用like’%%’这样的模糊查询来检索时,该怎么办??

接下来,笔者将会给大家分享解决这个问题的四种方法!


1)    Select主键

只要Select的字段刚好是主键,那么就会使用到索引(只对innodb数据库有效)

比如下面的

[plain]  view plain copy
  1. select idfrom emp where ename like '%haha%'\G  

就使用了索引


[plain]  view plain copy
  1. select * from empwhere ename like '%haha%'\G  

则不使用索引



除了主键,其他字段必须设置为覆盖索引才能使索引生效,不能单独设置索引

比如下面这种是不会使用索引的


可以采用分步查询的方法,先select主键再利用主键去找其他字段。不过好像比较麻烦!别怕!接下来会讲一种最优方法——覆盖索引法!


2)    覆盖索引法

覆盖索引是一种特殊的多列索引,当多列索引指向一个查询语句中所有的字段时,该多列索引就被称为覆盖索引。

使用覆盖索引可以解决问题!

创建覆盖索引


当然,如果你想要select很多字段甚至是select*,那你可以创建一个多列索引指向所有字段(innodb可以不指向主键)



注意:

笔者发现,当覆盖索引指向的字段是varchar(380)及380以上的字段时,覆盖索引会失效!

 

3)    全文索引法

此方法有较大局限。

全文索引,只对MyISAM引擎有用。主要是针对对文件,文本的检索, 比如文章或者段落,.

它会把某个数据表的某个数据列出现过的所有单词生成一份清单

少于3个字符的单词不会被包含在全文索引里,可以通过修改my.cnf修改选项

ft_min_word_len=3

但是!

全文索引不完全等同于模糊查询

比如title字段有这么个数据’abcd20088ccaa’,使用模糊查询select * from articles wheretitle like’%2008%’可以查找到,而使用全文检索select * from articles where match(title) against(‘2008’);是检索不到的,因为2008不是一个单词!

 

4)    使用全文检索引擎工具包

采用lucene、Sphinx、solr等专门的全文检索开源工具可以检索某段字符串。



本章结束,下一章将回归数据库的开发源头——设计好一张表。

四、           设计一张漂亮的表


上一章讲了如何通过索引来提速我们的查询语句,这一章让我们回到数据库开发的初始阶段,建表。谈谈怎样设计一张漂亮的表。


1.      满足三范式

1NF: 即表的列的具有原子性,不可再分解,即列的信息,不能分解, 只要数据库是关系型数据库(mysql/oracle/db2/informix/sysbase/sqlserver),就自动的满足1NF

 

数据库的分类

关系型数据库:  mysql/oracle/db2/informix/sysbase/sql server

非关系型数据库:  面向对象或者集合

面向文档数据库:   MongoDB

 

2NF: 表中的记录是唯一的, 就满足2NF, 通常我们设计一个主键来实现。一般情况下,表中都必须设置主键,并且一般不含业务逻辑,可以设置为自增长。

 

3NF: 即表中不要有冗余数据, 就是说,表的信息,如果能够被推导出来,就不应该单独的设计一个字段来存放.

有时候为了减少查询次数,可以容忍冗余。

 

2.      字段数目不要过多

一张表的字段过于庞大,会导致查询时的扫描范围加大,即使你并没有查询相应字段。

所以,如果一张表某个字段,信息量大,但是我们很少查询,则可以考虑把这些字段,单独的放入到一张表中,这种方式称为垂直分割

 

3.      选择合适的字段类型

在创建表的时候要选取最适用的字段属性。

一般说来,数据库中的表越小,在它上面执行的查询也就会越快。因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小

举个例子

11位的手机号

有两种类型可以存储

Bigint、char(11)。Int类型最大2147483647不可存

考虑到Bigint占20字节,而char(11)占11*2=22(gbk)或11*3=33(utf-8),所以使用bigInt是最好的。

 

如果在创建表之后发现表的字段设置不够合理想修改时怎么修改呢?


4.      修改表结构

如果发现表的字段设置不够合理想修改时怎么修改呢,有两种方法。

传统方法

先使用show createtable 查看原先怎样创建字段的

然后就可以根据需要修改了

[plain]  view plain copy
  1. alter table patent_data modify mingcheng varchar(500) DEFAULT NULL COMMENT '名称';  


快速方法(简单粗暴而高效)

创建一个结构是你所需要的空表,关闭mysql,在文件夹中直接复制新生成的表的frm文件替换掉原来表的的frm文件

注:

Frm文件位于mysql安装目录下的   /data/数据库名   目录下



本章结束,下一章将谈谈sql语句的优化方法。

上一章讲了如何设计一张好的表,一张好的表自然需要好的sql语句去操作它。本章就来聊聊如何优化sql语句。


1.      Sql语句优化原则

优化需要优化的Query

定位优化对象性能瓶颈

从Explain入手

尽可能在索引中完成排序

只取自己需要的Column

尽可能避免复杂的join和子查询

 

2.     优化limit

[plain]  view plain copy
  1. select * from test1 order by id limit 99999,10  

原语句虽然使用了id索引,但是相当于从第一行定位到99999行再去扫描后10行,相当于扫描全表

如果改为
[plain]  view plain copy
  1. select * from test1 where id>=100000 order by id limit 10  

则直接定位到100000查找


3.     尽量避免SELECT *命令


4.      不让排序

在使用group by 分组查询时,默认分组后,还会排序,可能会降低速度.

 

比如: 


在group by后面增加 order by null 就可以防止排序.


5.     使用连接来替代子查询

有些情况下,可以使用连接来替代子查询。因为使用join,MySQL不需要在内存中创建临时表。

[糟糕的效率]

[plain]  view plain copy
  1. select * from sales2 where company_id not in(select id from company2)  

[简单处理方式]

[plain]  view plain copy
  1. select * from dept, emp where dept.deptno=emp.deptno;   

[左外连接,效率最高]


[plain]  view plain copy
  1. select * from dept left join emp on dept.deptno=emp.deptno;    

6.     利用LIMIT 1取得唯一行

有时,当你要查询一张表是,你知道自己只需要看一行。在这种情况下,增加一个LIMIT 1会令你的查询更加有效。这样数据库引擎发现只有1后将停止扫描,而不是去扫描整个表或索引

 

7.     使用 EXISTS代替in

 EXISTS要远比IN的效率高。里面关系到full table scan和range scan。几乎将所有的IN操作符子查询改写为使用EXISTS的子查询

 

8.     不要手贱

没有必要时不要用DISTINCT和ORDER BY

这些动作可以改在客户端执行,它们增加了额外的开销



本章结束,下一章聊聊mysql数据库的其他优化方法。


六、           MySQL数据库其他优化方法


最后一章,谈谈前面没有涉及的一些优化方法。

1.      My.ini配置文件

这里只介绍两个最重要的,其他的不过多介绍。

1)    配置 最大连接数

默认为100,建议设为1000


2)   配置 缓存

在my.ini的[mysqld]节点开启查询缓存,配置如下

query_cache_size = 268435456

query_cache_type = 1

query_cache_limit = 1048576


2.      使用存储过程

存储过程相对sql语句来说的优点是:不需要编译,过程是一个已经编译好的对象


3.      水平分割

当一张越来越大时候,即使添加索引还慢的话,我们可以使用分表

 

4.      页面静态化

把每个请求最后生成的静态页面保存到服务器中,以后要是有相同的请求则直接显示静态页面。



整个数据库调优教程到此就该一段落了,算是把自己所学所用所得之经验都写进去了,如果同学们觉得有什么需要补充、有什么地方写的不好的,欢迎交流哈。

转载来自http://blog.youkuaiyun.com/hzy38324/article/category/3068221
Oracle EBS R12 AP模块发票导入接口实战:从SQL插入到API调用的完整流程 本文详细解析了Oracle EBS R12 AP模块发票导入接口的完整流程,从SQL插入到API调用的实战技巧。涵盖接口表设计、数据验证、双通道导入机制及错误诊断,特别分享官方文档未提及的高阶优化方案,助力企业实现财务数字化转型。 阅读详情

相关推荐

群晖NAS变身私有Git服务器:DS218+部署与TortoiseGit客户端实战指南

本文详细介绍了如何将群晖NAS(如DS218+)变身为私有Git服务器,并配置TortoiseGit客户端实现高效代码管理。通过硬件检查、系统更新、Git Server套件安装及权限配置等步骤,帮助开发者在局域网内搭建安全、高速的代码托管环境,特别适合小团队协作。

weixin_29252171的博客 224

sql调优的几种方式

sql调优的几种方式:避免使用select *、用union all 代替union、小表驱动大表、批量操作、多用limit、in中值太多、增量查询、高效的分页、用链接查询代替子查询、join数量不宜过多、join时需要注意、控制索引的数量、选择合理的字段类型、提升group by的效率、索引优化。

_江屿_ 9246

如何免费访问和使用Gemini API?

Gemini Ultra具有最先进的性能,在几个指标上超过了GPT-4的性能。它是第一个在大规模多任务语言理解基准测试中超越人类专家的模型,该基准测试57个不同学科的世界知识和解决问题的能力。Gemini是谷歌迄今为止开发的最先进、最庞大的AI模型。它为多模态而建,理解并处理不同类型的数据,比如文本、代码、音频、图像和视频。下面我们将加载Masood Aslami的图像,并用它来测试Gemini Pro Vision的多模态性。有了Gemini可以为查询提供图像、音频和文本,获得几乎完美的答案。

java_cjkl的博客 1万+

【MySQL调优】如何进行MySQL调优?一篇文章就够了!

MySQL调优主要分为三个步骤:监控报警、排查慢SQL、MySQL调优。 排查慢SQL:开启慢查询日志 、找出最慢的几条SQL、分析查询计划 。 MySQL调优: 基础优化:缓存优化、硬件优化、参数优化、定期清理垃圾、使用合适的存储引擎、读写分离、分库分表; 表设计优化:数据类型优化、冷热数据分表等。 索引优化:考虑索引失效的11个场景、遵循索引设计原则、连接查询优化、排序优化、深分页查询优化、覆盖索引、索引下推、用普通索引等。 SQL优化。

种一棵树最好的时间是十年前,其次是现在 3万+

OpenCV中SGBM中BT代价计算

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Mar

qq_27606639的博客 5978

MOS管关断时尖峰电压的5种实用抑制方案(附实测数据对比)

本文针对MOS管关断时产生的尖峰电压问题,提供了五种经过实验室实测验证的实用抑制方案。文章从尖峰电压的成因分析入手,详细阐述了优化PCB布局、设计RC缓冲电路、选用TVS二极管钳位、调节驱动电路以及使用磁珠吸收高频振荡等方法的原理、实施步骤与实测数据对比,为硬件工程师解决开关电源和电机驱动中的过压应力与EMI问题提供了系统性的实战指南。

1242

MySQL性能调优的10个方法(转载)-20230709

MySQL性能调优的10个方法

u010503464的博客 4899

3. LangGraph快速入门

本示例中,我们将使用 Claude Sonnet 4.5 模型,并定义加法、乘法、除法工具。# 定义工具@toolArgs:"""@toolArgs:"""@toolArgs:"""# 为大模型绑定工具图的状态用于存储消息和大模型调用次数。LangGraph 中的状态在整个智能体执行过程中保持持久化。使用带的Annotated类型可以确保新消息追加到现有列表,而不是替换列表。模型节点用于调用大模型,并决定是否调用工具。return {],

Long_像风一样自由 842

Sakila数据库和World数据库

安装MySQL8.2的时候多出两个样例数据库 Sakila数据库和World数据库

桃李不言下自成蹊 4万+

Qt入门教程【Core篇】singal and slot信号与槽

Qt中信号与槽singal and slot

小鱼酱的博客 2450

LVS 负载均衡面试题及参考答案

什么是 LVS 负载均衡?它的主要作用是什么? LVS(Linux Virtual Server)是一个基于 Linux 内核的开源负载均衡项目。它通过将请求流量按照一定的算法分发到后端的多个真实服务器(Real Server)上,从而实现负载均衡的功能。 从原理上来说,LVS 工作在网络层和传输层之间。当客户端发起请求时,请求首先到达 LVS 服务器,LVS 会根据预先设定的规则和算法,比如轮询(Round - Robin)、加权轮询(Weighted Round - Robin)、最少连

大模型大数据攻城狮的专栏 1469

SQL优化的方法

(1)建立物化视图或尽可能减少多表查询。(2)以不相干子查询替代相干子查询。(3)只检索需要的列。(4)用带in的条件子句等价替换or子句。(5)经常提交commit,以尽早释放锁。(6)避免嵌套的游标(Cursor)和多重循环等。(7)在经常查询的列上创建索引,提高查询效率。(8)避免使用模糊查询进行匹配,如果一定要使用,建议使用最左模糊匹配原则。(9)慢的查询的sql,根据性能和存储容量大小进行评估,适当的可以考虑水平分表和垂直分表,以提高sql的查询性能。

m0_45312259的博客 1万+

Python 爬虫实战:豆瓣电影海报批量获取(Top250 榜单 + 可视化展示)

在信息爆炸的时代,数据已成为决策的核心,而数据的获取是数据分析的第一步。本文将详细介绍如何利用 Python 爬虫获取豆瓣电影 Top250 榜单的海报,并对数据进行可视化展示,助你更好地了解电影市场的趋势和用户的喜好。

yansideyucsdn的博客 718

数据库调优教程(十三) MySQL数据库其他优化方法

最后一章,谈谈前面没有涉及的一些优化方法。

SexyCode 2632

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

MySQL8数据库 | MySQL调优|MySQL底层原理|MySQL零基础新手教程

CREATE TABLE tb_name (建表的字段、类型、长度、约束、默认、注释)6、重新启动 mysql 服务,再以无密码登录 mysql。3、前面窗口不能关闭,再开启一个新的窗口进行无密码登录。:复制保存 MySQL初始化密码。:复制保存 MySQL初始化密码。使用上面方式无法登录的解决方案。1、停止 mysql8。

xinghaoyan的专栏 827

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

MySQL与Redis性能调优:lnmp1/lnmp环境下数据库优化实战教程

在lnmp1/lnmp环境中,MySQL和Redis作为核心数据存储组件,其性能直接影响整个应用的响应速度和稳定性。本文将分享一套简单实用的数据库优化方案,帮助开发者在Docker容器环境下快速提升MySQL与Redis的运行效率,无需复杂的系统配置即可实现显著的性能改善。 ## MySQL性能优化核心配置 ### 启用慢查询日志定位性能瓶颈 慢查询日志是发现MySQL性能问题的重要工具。在l

gitblog_00565的博客 683

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

MYSQL基础:参数调优:4:常见的缓存调优参数

这篇文章整理一下缓存相关常用的调优参数,并给出建议。

知行合一 止于至善 4148

分享免费视频教程:mysql数据库入门基础精讲

分享免费视频教程:mysql数据库入门基础精讲   目前MySQL已经成为最为流行的开源关系数据库系统,并且一步一步地占领了原有商业数据库的市场。 学习目标: 深入理解MySQL数据库的原理 从硬件 系统 MySQL参数 执行计划 SQL优化等多角度学习MySQL的性能调优技术 掌握基于MySQL的架构设计方案 课程目录: 第1节 MySQL课程介绍和MySQL的基础概念(1

x910378112的博客 1886

【精】Mysql性能调优 资料

https://github.com/bjmashibing/InternetArchitect/tree/master/13mysql%E8%B0%83%E4%BC%98

wssjdysf1的专栏 174

innobackex工具备份mysql数据 mysql5.7root密码更改 mysql调优 mysql字符集调整

mysql5.7root有默认密码,必须重设密码后,才能进行mysql的操作,以下是设置root密码的步骤: 一、查看默认密码 [root@localhost src]# cat /root/.mysql_secret # The random password set for th...

chuangu7098的博客 182

Linux系统MySQL数据库性能优化详细教程。

请注意,MySQL性能优化是一个复杂的过程,需要根据具体的环境和应用进行调整。建议在进行任何更改之前,备份数据库并测试性能影响。希望这个教程对您有所帮助。如有任何疑问,请随时提问。

高性价比服务器就选:蓝易云 1085

数据库调优教程汇总

这两个星期来把自己所学所思及所用加以总结,发表了关于数据库系列的一系列文章。现将这系列文章进行汇总,方便大家查阅。

SexyCode 4076

PHP特级视频教程 笔记心得  第十七集 mysql调优,mysql优化 MySQL基础操作(一)

PHP特级视频教程 笔记心得  第十七集 mysql调优,mysql优化 MySQL基础操作(一) mysql中使用正则表达式:利用 regexp命令提供给用户扩展的正则表达式功能。 js里面的正则表达最为标准。贴近perl的正则。 select  name  from  t where  email  REGEXP "@163[.,]com" select  name  from  t

Ai大模型,odoo,idempiere,metasfresh,低代码,ecshop数据采集发布接口,zencart,lightinthebox,shopex 数据采集接口 872

视频教程-15天入门MySQL和高性能调优视频教程-MySQL

15天入门MySQL和高性能调优视频教程 负责过多个软件项目的研发、设计和管...

weixin_30482105的博客 462

记一次mysql调优

首先需要明白现有配置性能,然后调优,才能量化调优量 mysql原理:https://blog.youkuaiyun.com/xianqi45/article/details/78841811 mysqlslap测试:http://www.ha97.com/5182.html https://blog.youkuaiyun.com/u012279631/article/details/80686633 字段修改建议:select * from tem_statistics procedure analyse(1,256) ;

水工土成 231
上一篇: vxWorks多任务编程
下一篇: 用Ant实现Java项目的自动构建和部署
World_2015
博客等级 码龄12年 25粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值