mysql数据库优化五步走

MySQL数据库是一种小型关系型数据库管理系统,MySQL数据库的优化是MySQL数据库操做过程当中很是重要的工做,MySQL数据库的优化可以实现MySQL数据库操做的简便。 mysql

第一步: linux

1:磁盘寻道能力,以高速硬盘(7200转/秒),理论上每秒寻道7200次.这是没有办法改变的,优化的方法是----用多个硬盘,或者把数据分散存储. sql

2:硬盘的读写速度,这个速度很是的快,这个更容易解决--能够从多个硬盘上并行读写. shell

3:cpu.cpu处理内存中的数据,当有相对内存较小的表时,这是最多见的限制因素. 数据库

4:内存的限制.当cpu须要超出适合cpu缓存的数据时,缓存的带宽就成了内存的一个瓶颈---不过如今内存大的惊人,通常不会出现这个问题. express

第二步: (本人使用的是学校网站的linux平台(Linux ADVX.Mandrakesoft.com 2.4.3-19mdk )) 缓存

1:调节服务器参数 安全

用shell>mysqld-help这个命令声厂一张全部mysql选项和可配置变量的表.输出如下信息: 服务器

possible variables for option--set-variable(-o) are: mysql优化

back_log current value:5 //要求mysql能有的链接数量.back_log指出在mysql暂停接受链接的时间内有多少个链接请求能够被存在堆栈中

connect_timeout current value:5 //mysql服务器在用bad handshake(很差翻译)应答前等待一个链接的时间

delayed_insert_timeout current value:200 //一个insert delayed在终止前等待insert的时间

delayed_insert_limit current value:50 //insert delayed处理器将检查是否有任何select语句未执行,若是有,继续前执行这些语句

delayed_queue_size current value:1000 //为insert delayed分配多大的队

flush_time current value:0 //若是被设置为非0,那么每一个flush_time 时间,全部表都被关闭

interactive_timeout current value:28800 //服务器在关上它以前在洋交互链接上等待的时间

join_buffer_size current value:131072 //用与所有链接的缓冲区大小

key_buffer_size current value:1048540 //用语索引块的缓冲区的大小,增长它能够更好的处理索引

lower_case_table_names current value:0 //

long_query_time current value:10 //若是一个查询所用时间大于此时间,slow_queried计数将增长

max_allowed_packet current value:1048576 //一个包的大小

max_connections current value:300 //容许同时链接的数量

max_connect_errors current value:10 //若是有多于该数量的中断链接,将阻止进一步的链接,能够用flush hosts来解决

max_delayed_threads current value:15 //能够启动的处理insert delayed的数量

max_heap_table_size current value:16777216 //

max_join_size current value:4294967295 //容许读取的链接的数量

max_sort_length current value:1024 //在排序blob或者text时使用的字节数量

max_tmp_tables current value:32 //一个链接同时打开的临时表的数量

max_write_lock_count current value:4294967295 //指定一个值(一般很小)来启动mysqld,使得在必定数量的write锁定以后出现read锁定

net_buffer_length current value:16384 //通讯缓冲区的大小--在查询时被重置为该大小

query_buffer_size current value:0 //查询时缓冲区大小

record_buffer current value:131072 //每一个顺序扫描的链接为其扫描的每张表分配的缓冲区的大小

sort_buffer current value:2097116 //每一个进行排序的链接分配的缓冲区的大小

table_cache current value:64 //为全部链接打开的表的数量

thread_concurrency current value:10 //

tmp_table_size current value:1048576 //临时表的大小

thread_stack current value:131072 //每一个线程的大小

wait_timeout current value:28800 //服务器在关闭它3以前的一个链接上等待的时间

根据本身的须要配置以上信息会对你帮助.

第三步:

1:若是你在一个数据库中建立大量的表,那么执行打开,关闭,建立(表)的操做就会很慢. 2:mysql使用内存

a: 关键字缓存区(key_buffer_size)由全部线程共享

b: 每一个链接使用一些特定的线程空间.一个栈(默认为64k,变量thread_stack),一个链接缓冲区(变量net_buffer_length)和一个结果缓冲区(net_buffer_length).特定状况下,链接缓冲区和结果缓冲区被动态扩大到max_allowed_packet.

c:全部线程共享一个基存储器

d:没有内存影射

e:每一个作顺序扫描的请求分配一个读缓冲区(record_buffer)

f:全部联结均有一遍完成而且大多数联结甚至能够不用一个临时表完成.最临时的表是基于内存的(heap)表

g:排序请求分配一个排序缓冲区和2个临时表

h:全部语法分析和计算都在一个本地存储器完成

i:每一个索引文件只被打开一次,而且数据文件为每一个并发运行的线程打开一次

j:对每一个blob列的表,一个缓冲区动态的被扩大以便读入blob值

k:全部正在使用的表的表处理器被保存在一个缓冲器中而且做为一个fifo管理.

l:一个mysqladmin flush-tables命令关闭全部不在使用的表而且在当前执行的线程结束时标记全部在使用的表准备关闭

3:mysql锁定表

mysql中全部锁定不会成为死锁. wirte锁定: mysql的锁定原理:a:若是表没有锁定,那么锁定;b不然,把锁定请求放入写锁定队列中

read锁定: mysql的锁定原理:a:若是表没有锁定,那么锁定;b不然,把锁定请求放入读锁定队列中

有时候会在一个表中进行不少的select,insert操做,能够在一个临时表中插入行而且偶尔用临时表的记录更新真正的表

a:用low_priority属性给一个特定的insert,update或者delete较低的优先级

b:max_write_lock_count指定一个值(一般很小)来启动mysqld,使得在必定数量的write锁定以后出现read锁定

c:经过使用set sql_low_priority_updates=1能够从一个特定的线程指定全部的更改应该由较低的优先级完成

d:用high_priority指定一个select

e:若是使用insert....select....出现问题,使用myisam表------由于它支持由于它支持并发的select和insert

4:最基本的优化是使数据在硬盘上占据的空间最小.若是索引作在最小的列上,那么索引也最小.实现方法:

a:使用尽量小的数据类型

b:若是可能,声明表列为NOT NULL.

c:若是有可能使用变成的数据类型,如varchar(可是速度会受必定的影响)

d:每一个表应该有尽量短的主索引 e:建立确实须要的索引

f:若是一个索引在头几个字符上有惟一的前缀,那么仅仅索引这个前缀----mysql支持在一个字符列的一部分上的索引

g:若是一个表常常被扫描,那么试图拆分它为更多的表

第四步

1:索引的使用,索引的重要性就不说了,功能也不说了,只说怎么作. 首先要明确全部的mysql索引(primary,unique,index)在b树中有存储.索引主要用语:

a:快速找到where指定条件的记录 b:执行联结时,从其余表检索行 c:对特定的索引列找出max()和min()值

d:若是排序或者分组在一个可用键的最前面加前缀,排序或分组一个表

e:一个查询可能被用来优化检索值,而不用访问数据文件.若是某些表的列是数字型而且正好是某个列的前缀,为了更快,值能够从索引树中取出

2:存储或者更新数据的查询速度  grant的执行会稍稍的减低效率.

mysql的函数应该被高度的优化.能够用benchmark(loop_count,expression)来找出是否查询有问题

select的查询速度:若是想要让一个select...where...更快,我能想到的只有创建索引.能够在一个表上运行myisamchk--analyze来更好的优化查询.能够用myisamchk--sort-index--sort-records=1来设置用一个索引排序一个索引和数据.

3:mysql优化where子句

3.1:删除没必要要的括号:

((a AND b) AND c OR (((a AND b) AND (a AND d))))>(a AND b AND c) OR (a AND b AND c AND d)

3.2:使用常数

(ab>5 AND b=c AND a=5

3.3:删除常数条件

(b>=5 AND b=5) OR (b=6 AND 5=5) OR (b=100 AND 2=3) >b=5 OR b=6

3.4:索引使用的常数表达式仅计算一次

3.5:在一个表中,没有一个where的count(*)直接从表中检索信息

3.6:全部常数的表在查询中在任何其余表以前读出

3.7:对外联结表最好联结组合是尝试了全部可能性找到的

3.8:若是有一个order by字句和一个不一样的group by子句或者order by或者group by包含不是来自联结的第一个表的列,那么建立一个临时表

3.9:若是使用了sql_small_result,那么msyql使用在内存中的一个表

3.10:每一个表的索引给查询而且使用跨越少于30%的行的索引.

3.11在每一个记录输出前,跳过不匹配having子句的行

4:优化left join

在mysql中 a left join b按如下方式实现

a:表b依赖于表a

b:表a依赖于全部用在left join条件的表(除了b)

c:全部left join条件被移到where子句中

d:进行全部的联结优化,除了一个表老是在全部他依赖的表后读取.若是有一个循环依赖,那么将发生错误

e:进行全部的标准的where优化 f:若是在a中有一行匹配where子句,可是在b中没有任何匹配left join条件,那么,在b中生成的全部设置为NULL的一行

g:若是使用left join来找出某些表中不存在的行而且在where部分有column_name IS NULL测试(column_name为NOT NULL列).那么,mysql在它已经找到了匹配left join条件的一行后,将中止在更多的行后寻找

5:优化limit

a:若是用limit只选择一行,当mysql须要扫描整个表时,它的做用至关于索引

b:若是使用limit#与order by,mysql若是找到了第#行,将结束排序,而不会排序正个表

c:当结合limit#和distinct时,mysql若是找到了第#行,将中止

d:只要mysql已经发送了第一个#行到客户,mysql将放弃查询

e:limit 0一直会很快的返回一个空集合.

f:临时表的大小使用limit#计算须要多少空间来解决查询

6:优化insert

插入一条记录的是由如下构成:

a:链接(3)

b:发送查询给服务器(2)

c:分析查询(2)

d:插入记录(1*记录大小)

e:插入索引(1*索引)

f:关闭(1)

以上数字能够当作和总时间成比例

改善插入速度的一些方法:

6.1:若是同时从一个链接插入许多行,使用多个值的insert,这比用多个语句要快

6.2:若是从不一样链接插入不少行,使用insert delayed语句速度更快

6.3: 用myisam,若是在表中没有删除的行,能在select:s正在运行的同时插入行

6.4: 当从一个文本文件装载一个表时,用load data infile.这个一般比insert快20 倍

6.5:能够锁定表而后插入--主要的速度差异是在全部insert语句完成后,索引缓冲区仅被存入到硬盘一次.通常与有不一样的insert语句那样屡次存入要快.若是能用一个单个语句插入全部的行,锁定就不须要.锁定也下降链接的总体时间.可是对某些线程最大等待时间将上升.例如:

thread 1 does 1000 inserts

thread 2,3 and 4 does 1 insert

thread 5 does 1000 inserts

若是不使用锁定,2,3,4将在1和5以前完成.若是使用锁定,2,3,4,将可能在1和5以后完成.可是总体时间应该快40%.由于insert,update,delete操做在mysql中是很快的,经过为多于大约5次接二连三的插入或更新一行的东西加锁,将得到更好的总体性能.若是作不少一行的插入,能够作一个lock tables,偶尔随后作一个unlock tables(大约每1000行)以容许另外的线程存取表.这仍然将致使得到好的性能.load data infile对装载数据仍然是很快的.

为了对load data infile和insert获得一些更快的速度,扩大关键字缓冲区.

7优化update的速度

它的速度依赖于被更新数据的大小和被更新索引的数量

使update更快的另外一个方法是推迟修改,而后一行一行的作不少修改.若是锁定表,作一行一行的不少修改比一次作一个快

8优化delete速度

删除一个记录的时间与索引数量成正比.为了更快的删除记录,能够增长索引缓存的大小 从一个表删除全部行比删除这个表的大部分要快的多

第五步

1:选择一种表类型 1.1静态myisam

这种格式是最简单且最安全的格式,它是磁盘格式中最快的.速度来自于数据能在磁盘上被找到的难易程度.当锁定有一个索引和静态格式的东西是,它很简单,只是行长度乘以数量.并且在扫描一张表时,每次用磁盘读取来读入常数个记录是很容易的.安全性来源于若是当写入一个静态myisam文件时致使计算机down掉,myisamchk很容易指出每行在哪里开始和结束,所以,它一般能收回全部记录,除了部分被写入的记录.在mysql中全部索引总能被重建

1.2动态myisam

这种格式每一行必须有一个头说明它有多长.当一个记录在更改期间变长时,它能够在多于一个位置上结束.能使用optimize tablename或myisamchk整理一张表.若是在同一个表中有像某些varchar或者blob列那样存取/改变的静态数据,将动态列移入另一个表以免碎片.

1.2.1压缩myisam,用可选的myisampack工具生成

1.2.2内存

这种格式对小型/中型表颇有用.对拷贝/建立一个经常使用的查找表到洋heap表有可能加快多个表联结,用一样数据可能要快好几倍时间.

select tablename.a,tablename2.a from tablename,tablanem2,tablename3 where

tablaneme.a=tablename2.a and tablename2.a=tablename3.a and tablename2.c!=0;

为了加速它,能够用tablename2和tablename3的联结建立一个临时表,由于用相同列(tablename1.a)查找.

CREATE TEMPORARY TABLE test TYPE=HEAP

SELECT

tablename2.a as a2,tablename3.a as a3

FROM

tablenam2,tablename3

WHERE

tablename2.a=tablename3.a and c=0;

SELECT tablename.a,test.a3 from tablename,test where tablename.a=test.a1;

SELECT tablename.a,test,a3,from tablename,test where tablename.a=test.a1 and ....;

1.3静态表的特色

1.3.1默认格式.用在表不包含varchar,blob,text列的时候

1.3.2全部的char,numeric和decimal列填充到列宽度

1.3.3很是快

1.3.4容易缓冲

1.3.5容易在down后重建,由于记录位于固定的位置

1.3.6没必要被从新组织(用myisamchk),除非是一个巨量的记录被删除而且优化存储大小

1.3.7一般比动态表须要更多的存储空间

1.4动态表的特色

1.4.1若是表包含任何varchar,blob,text列,使用该格式

1.4.2全部字符串列是动态的

1.4.3每一个记录前置一个位.

1.4.4一般比定长表须要更多的磁盘空间

1.4.5每一个记录仅仅使用所须要的空间,若是一个记录变的很大,它按须要被分红不少段,这致使了记录碎片

1.4.6若是用超过行长度的信息更新行,行被分段.

1.4.7在系统down掉之后很差重建表,由于一个记录能够是多段

1.4.8对动态尺寸记录的指望行长度是3+(number of columns+7)/8+(number of char columns)+packed size of numeric columns+length of strings +(number of NULL columns+7)/8

对每一个链接有6个字节的惩罚.不管什么时候更改引发记录的变大,都有一个动态记录被链接.每一个新链接至少有20个字节,所以下一个变大将可能在同一个链接中.若是不是,将有另一个链接.能够用myisamchk -恶毒检查有多少链接.全部链接能够用myisamchk -r删除.

1.5压缩表的特色

1.5.1一张用myisampack实用程序制做的只读表.

1.5.2解压缩代码存在于全部mysql分发中,以便使没有myisampack的链接也能读取用myisampack压缩的表

1.5.3占据很小的磁盘空间

1.5.4每一个记录被单独压缩.一个记录的头是一个定长的(1~~3个字节)这取决于表的最大记录.每列以不一样的方式被压缩.一些经常使用的压缩类型是:

a:一般对每列有一张不一样的哈夫曼表  b:后缀空白压缩  c:前缀空白压缩 d:用值0的数字使用1位存储

e:若是整数列的值有一个小范围,列使用最小的可能类型来存储.例如:若是全部的值在0到255之间,一个bigint能够做为一个tinyint存储

g:若是列仅有可能值的一个小集合,列类型被转换到enum  h:列可使用上面的压缩方法的组合

1.5.5能处理定长或动态长度的记录,去不能处理blob或者text列 1.5.6能用myisamchk解压缩

mysql能支持不一样的索引类型,但通常的类型是isam,这是一个B树索引而且能粗略的为索引文件计算大小为(key_length+4)*0.67,在全部的键上的总和.

字符串索引是空白压缩的。若是第一个索引是一个字符串,它可将压缩前缀若是字符串列有不少尾部空白或是一个总部能甬道全长的varchar列,空白压缩使索引文件更小.若是不少字符串有相同的前缀.

1.6内存表的特色

mysql内部的heap表使用每偶溢出去的100%动态哈希而且没有与删除有关的问题.只能经过使用在堆表中的一个索引来用等式存取东西(一般用'='操做符)

堆表的缺点是:

1.6.1想要同时使用的全部堆表须要足够的额外内存

1.6.2不能在索引的一个部分搜索

1.6.3不能按顺序搜索下一个条目(即,使用这个索引作一个order by)

1.6.4mysql不能算出在2个值之间大概有多少行.这被优化器使用是用来决定使用哪一个索引的,可是在另外一个方面甚至不须要磁盘寻道

经过上文中介绍的这五步就可以实现MySQL数据库的优化工做,但愿你们都可以从上文中涉及到的内容中有所收获。

相关文章
相关标签/搜索