转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 数据库 >> MySql >> 正文
mysql数据库优化(未完....待续....)         ★★★★

mysql数据库优化(未完....待续....)

作者:闵涛 文章来源:闵涛的学习笔记 点击数:1456 更新时间:2009/4/22 20:48:46

#######################################
#文件名:mysqloptimize,php                           #
#主题: mysql数据库的优化                  #
#作者: _Shakespeare(网络骑士)                    #
#最后修改时间: 2002--09--20                      #
#e-mail: shakespareshmily@sina.com.cn         #
#######################################
下决心开始学oracle了,用mysql已经有不短的时间了,今天写下这些算是对自己的一个mysql之旅的一个交代吧.以下仅仅是本人在使用mysql过程中的一点个人的体会,也许存在许多纰漏和错误,还请指正!!

首先,为了使一个系统更快,最重要的部分就是基础设计,不过有些东西是现有情况下无法逾越的,比如说系统常见的瓶颈.
我所能想到的:
1:磁盘寻道能力,以高速硬盘(7200转/秒),理论上每秒寻道7200次.这是没有办法改变的,优化的方法是----用多个硬盘,或者把数据分散存储.
2:硬盘的读写速度,这个速度非常的快(限于本人的知识所限,只知道在每秒几十甚至上百MB).这个更容易解决--可以从多个硬盘上并行读写.
3:cpu.cpu处理内存中的数据,当有相对内存较小的表时,这是最常见的限制因素.
4:内存的限制.当cpu需要超出适合cpu缓存的数据时,缓存的带宽就成了内存的一个瓶颈---不过现在内存大的惊人,一般不会出现这个问题.
第二步:
(本人使用的是学校网站的linux平台(Linux ADVX.Mandrakesoft.com 2.4.3-19mdk ))
1:调节服务器参数
用shell>mysqld-help这个命令声厂一张所有mysql选项和可配置变量的表.输出以下信息:
possible variables for option--set-variable(-o) are:
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:使用常数
 (a<b AND b=c) AND a=100 > b>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
   S

[1] [2]  下一页


没有相关教程
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · Sql Server  · MySql
    · Access  · ORACLE
    · SyBase  · 其他
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台