发布新日志

  • mysql查询语句的优化

    2007-10-23 11:59:08Digest 3

    查询语句的优化
    多多利用 "explain" 查询索引使用情况, 以便找出最佳的查询语句写法和索引设置方案
    慎用 "select *", 查询时只选出必须字段
    查询使用索引时, 所遍历的索引条数越少, 索引字段长度越小, 查询效率越高 (可使用 "explain" 查询索引使用情况)
    避免使用 mysql 函数对查询结果进行处理, 将这些处理交给客户端程序负责
    使用 "limit" 时候, 尽量使 "limit" 出的部分位于整个结果集的前部, 这样的查询速度更快, 系统资源开销更低
    在 "where" 子句中使用多个字段的 "and" 条件时, 各个字段出现的先后顺序要与多字段索引中的顺序相符
    在 "where" 子句 中使用 "like" 时, 只有当通配符不出现在条件的最左端时才会使用索引
    在 mysql 4.1 以上版本中, 避免使用子查询, 尽量使用 "内/外连接" 实现此功能
    减少函数的使用, 如果可能的话, 尽量用单纯的表达式来代替
    避免在 "where" 子句中, 对不同字段进行 "or" 条件查询, 将其拆分成多个单一字段的查询语句效率更高


    从数据库结构做起
    字段类型的定义时遵循以下规则:
    选用字段长度最小
    优先使用定长型
    尽可能的定义 "NOT NULL"
    数值型字段中避免使用 "ZEROFILL"
    如果要储存的数据为字符串, 且可能值已知且有限, 优先使用 enum 或 set
    索引的优化至关重要(以下如果没有特殊说明, 均指查询密集的情况)
    被索引的字段的长度越小, 该索引的效率越高
    被索引的字段中, 值的重复越少, 该索引的效率越高
    查询语句中, 如果使用了 "group" 子句, 根据其中字段出现的先后顺序建立多字段索引
    查询语句中, 如果使用了 "distinct", 根据其中字段出现的先后顺序建立多字段索引
    "where" 子句中, 出现对同一表中多个不同字段的 "and" 条件时, 按照字段出现的先后顺序建立多字段索引
    "where" 子句中, 出现对同一表中多个不同字段的 "or" 条件时, 对重复值最少的字段建立单字段索引
    进行 "内/外连接" 查询时, 对 "连接字段" 建立索引
    对 "主键" 的 "unique" 索引 毫无意义, 不要使用
    被索引字段尽可能的使用 "NOT NULL" 属性
    对写入密集型表, 尽量减少索引, 尤其是 "多字段索引" 和 "unique" 索引

  • 火狐浏览器如何完全屏蔽Flash

    2007-10-15 09:20:23Digest 2

    火狐浏览器如何完全屏蔽Flash

    有一些网站由于放置太多的,会导致火狐浏览器占用很多内存,让电脑速度变得很慢。那么如何完全屏蔽掉网站内FLASH的显示呢?

    有两种方法可以解决这个问题:

    1.在火狐浏览器的地址栏中输入“about:config”,找到plugin.default_plugin_disabled,将其设置为false;

    2.下载一个叫做Flashblock的扩展插件,它能够阻止网页中Macromedia Flash、Macromedia Shockwave、Macromedia Authorware等内容。

  • 利用isapi_rewrite防盗链

    2007-10-04 16:52:36Digest 4

    利用isapi_rewrite防盗链

    • 作者:剧毒
    • 文章来源:剧毒博客

    利用isapi_rewrite可以实现类似于Apache的伪静态路径,利用其检查refer的功能我们还可以实现防盗链。该软件可以在 http://www.helicontech.com/download/下载,是一个共享软件,但是有一个LITE版本是免费的,基本上可以实现我们需要的功能。安装的步骤我就不详细说了,具体说说httpd.ini的设置。
    首先,必须要保证httpd.ini有可写权限,设置isapi_rewrite安装文件夹everyone具有可修改权限后,去除该文件的只读属性。
    httpd.ini默认设置如下:

    RewriteCond Host: (.+)
    RewriteCond Referer: (?!http://\1.*).*

    我们在它后面加上一句

    RewriteRule .*\.(?:gif|jpg|png|exe|rar|zip) /block.gif [I,O]

    即可实现gif/jpg/png/exe/rar/zip文件的防盗链,盗链页面显示的是/block.gif。block.gif是一个体积较少的图片文件,我们可以在上面打上自己网站的版权标志和防盗链声明。
    如果按照上面设置,则除本站以外的所有网站均不能使用这里的图片,如果要允许一些例外的网站比如google,baidu以及其它一些非营利性网站引用该怎么办呢?我们可以用如下正则表达式来实现

    RewriteCond Referer: (?!http://(?:www\.0e2\.net|www\.google\.com|www\.baidu\.com)).+


    如果想允许所有google子站和baidu子站形如images.baidu.com,images.google.com等站则做如下设置:

    RewriteCond Referer: (?!http://(?:*\.0e2\.net|*\.google\.com|*\.baidu\.com)).+


    至此,一个相当有效的防盗链系统已经出来了,但如上设置有一个问题,如果浏览者浏览了盗链页面后访问本站页面,则被盗链图片的缓存会影响图片的正常显示。把

    RewriteRule .*\.(?:gif|jpg|png|exe|rar|zip) /block.gif [I,O]

    改为

    RewriteRule .*\.(?:gif|jpg|png|exe|rar|zip) /block.gif [I,O,N]

    方可。参数N的意思是重新从站点请求文件而不是从本地缓存读取。

  • mysql 慢查询分析

    2007-09-25 13:49:01Digest 4

    mysql 慢查询分析

    Posted byglen | inLinux/BSD | 发布日期:2007-07-15 22:10:44 | 总浏览:233 | [评论本文]

    mysql有一个功能就是可以log下来运行的比较慢的sql语句,默认是没有这个log的,为了开启这个功能,要修改my.cnf或者在mysql启动的时候加入一些参数。

    如果在my.cnf里面修改,需增加如下几行

    long_query_time = 1
    log-slow-queries =
    log-queries-not-using-indexes

    long_query_time 是指执行超过多久的sql会被log下来,这里是1秒。
    log-slow-queries 设置把日志写在那里,可以为空,系统会给一个缺省的文件log-queries-not-using-indexes 就是纪录没使用索引的sql
    分析:
    mysqldumpslow –help以下,主要用的是
    -s ORDER what to sort by (t, at, l, al, r, ar etc), ‘at’ is default
    -t NUM just show the top n queries
    -g PATTERN grep: only consider stmts that include this string

    -s,是order的顺序,说明写的不够详细,俺用下来,包括看了代码,主要有
    c,t,l,r和ac,at,al,ar,分别是按照query次数,时间,lock的时间和返回的记录数来排序,前面加了a的时倒叙
    -t,是top n的意思,即为返回前面多少条的数据
    -g,后边可以写一个正则匹配模式,大小写不敏感的

    mysqldumpslow -s c -t 20 host-slow.log
    mysqldumpslow -s r -t 20 host-slow.log

    上述命令可以看出访问次数最多的20个sql语句和返回记录集最多的20个sql。
    mysqldumpslow -t 10 -s t -g “left join” host-slow.log
    这个是按照时间返回前10条里面含有左连接的sql语句。

    Time: 060908 22:17:43
    # Query_time: 12 Lock_time: 0 Rows_sent: 86345 Rows_examined: 580963
    Q:这个是慢查的日志,都是些什么意思?
    A:查询用了12妙,返回86345行,一共查了580963行

  • MySQL 优化相关的一些说明

    2007-09-25 13:49:01Digest 5

    以下是 MySQL 优化相关的一些说明:

    1、检验 key_buffer_size 参数大小是否合适(适用 MyISAM 表)

    key_buffer_size 指定索引缓冲区的大小,它决定索引处理的速度,尤其是索引读的速度。通过检查状态值Key_read_requests和Key_reads,可以知道 key_buffer_size设置是否合理。比例key_reads / key_read_requests应该尽可能的低,至少是1:100,1:1000更好(上述状态值可以使用SHOW STATUS LIKE ‘key_read%’获得)(检查状态值,在查询工具里输入 SHOW STATUS ,执行)。

    key_buffer_size只对MyISAM表起作用。即使你不使用MyISAM表,但是内部的临时磁盘表是MyISAM表,也要使用该值。可以使用检查状态值created_tmp_disk_tables得知详情。


    对于1G内存的机器,如果不使用MyISAM表,推荐值是16M(8-64M)。



    案例1:健康状况

    key_buffer_size – 402649088 (384M)

    key_read_requests – 597579931

    key_reads - 56188

    案例2:警报状态

    key_buffer_size – 16777216 (16M)

    key_read_requests – 597579931

    key_reads - 53832731

    案例1中比例低于1:10000,是健康的情况;案例2中比例达到1:11,警报已经拉响。


    2、查询缓存 query_cache_size 设置

    从 4.0.1 开始,MySQL 提供了查询缓冲机制。在启用查询缓冲的情况下,MySQL 将 SELECT 语句和查询结果存放在缓冲区中(内存),之后对于同样的 SELECT 查询语句(区分大小写),将直接从缓冲区中读取结果,避免了重复查询的无谓开销。和查询缓存相关的参数包括:Qcache_free_blocks、 Qcache_lowmem_prunes、Qcache_free_memory、Qcache_not_cached、 Qcache_total_blocks、Qcache_queries_in_cache、Qcache_hits、Qcache_inserts。其 中,如果 Qcache_lowmem_prunes 的值很大,说明经常出现缓冲不够的情况(最好保持在零),同时 Qcache_hits 的值非常大,则表明查询缓冲使用非常频繁,此时需要增加缓冲大小 Qcache_hits 的值不大,则表明你的查询重复率很低,这种情况下使用查询缓冲反而会影响效率,那么可以考虑不用查询缓冲。另外,如果 Qcache_free_blocks 的值非常大,则表明缓冲区中碎片很多。

    3、table_cache


    吴威 (16:59:27):
    table_cache
    The number of open tables for all threads ????

    For more information about the table cache, see section 7.4.8 How MySQL Opens and Closes Tables


    table_cache 用于指定表高速缓存的大小。每当 MySQL 访问一个表时,如果在表缓冲区中还有空间,该表就被打开并放入其中,这样可以更快地访问表内容。通过检查运行峰值时间的 Open_tables 和 Opened_tables 状态值,可以决定是否需要调整 table_cache 的值。如果你发现 open_tables 的值等于 table_cache,并且发现 opened_tables 状态值在不断增长,那么你就需要增加 table_cache 参数值了(上述状态值可以使用 SHOW STATUS LIKE ‘Open%tables’ 命令获得)。注意,不能盲目地把 table_cache 参数设置成很大的值,如果设置得太高,可能会造成文件描述符不足,从而造成性能不稳定或者连接失败。



    对于有1G内存的机器,推荐值是128-256。

    案例1:该案例来自一个不是特别繁忙的服务器

    table_cache – 512

    open_tables – 103

    opened_tables – 1273

    uptime – 4021421 (measured in seconds)

    该案例中table_cache似乎设置得太高了。在峰值时间,打开表的数目比table_cache要少得多。



    案例2:该案例来自一台开发服务器。

    table_cache – 64

    open_tables – 64

    opened-tables – 431

    uptime – 1662790 (measured in seconds)

    虽然open_tables已经等于table_cache,但是相对于服务器运行时间来说,opened_tables的值也非常低。因此,增加table_cache的值应该用处不大。



    案例3:该案例来自一个upderperforming的服务器

    table_cache – 64

    open_tables – 64

    opened_tables – 22423

    uptime – 19538

    该案例中table_cache设置得太低了。虽然运行时间不到6小时,open_tables达到了最大值,opened_tables的值也非常高。这样就需要增加table_cache的值。



    4、Measuring Key Buffer Usage

    When you add indexes to your data, it enables MySQL to find data faster. However, ideally you want to have these indexes stored in RAM for maximum speed, and the variable key_buffer_size defines how much RAM MySQL can allocate for index key caching. If MySQL cannot store its indexes in RAM, you will experience serious performance problems. Fortunately, most databases have relatively small key buffer requirements, but you should measure your usage to see what work needs to be done.

    To do this, log in to MySQL and type SHOW STATUS LIKE ‘%key_read%’;. That returns all the status fields that describe the hit rate of your key buffer—you should get two rows back: Key_reads and Key_read_requests, which are the number of keys being read from disk and the number of keys being read from the key buffer. From these two numbers you can calculate the percentage of requests being filled from RAM and from disk, using this simple equation:

    100 – ((Key_reads / Key_read_requests) x 100)

    That is, you divide Key_reads by Key_read_requests, multiply the result by 100 and then subtract the result from 100. For example, if you have Key_reads of 1000 and Key_read_requests of 100000, you divide 1000 by 100000 to get 0.01; then you multiply that by 100 to get 1.0, and subtract that from 100 to get 99. That number is the percentage of key reads being served from RAM, which means 99% of your keys are served from RAM.

    Most people should be looking to get more than 95% served from RAM, although the primary exception is if you update or delete rows very often—MySQL can’t cache what keeps changing. If your site is largely read only, this should be around 98%. Lower figures mean you might need to bump up the size of your key buffer.

    If you are seeing problems, the next step is to check how much of your current key buffer is being used. Use the SHOW VARIABLES command and look up the value of the key_buffer_size variable. It is probably something like 8388600, which is eight million bytes, or 8MB. Now, use the SHOW STATUS command and look up the value of Key_blocks_used.

    You can now determine how much of your key buffer is being used by multiplying Key_blocks_used by 1024, dividing by key_buffer_size, and multiplying by 100. For example, if Key_blocks_used is 8000, you multiply that by 1024 to get 8192000; then you divide that by your key_buffer_size (8388600) to get 0.97656, and finally multiplying that by 100 to get 97.656. Thus, almost 98% of your key buffer is being used.

    Now, onto the important part: You have ascertained that you are reading lots of keys from disk, and you also now know that the reason for reading from disk is almost certainly because you do not have enough RAM allocated to the key buffer. A general rule of thumb is to allocate as much RAM to the key buffer as you can, up to a maximum of 25% of system RAM—128MB on a 512MB system is about the ideal for systems that read heavily from keys. Beyond that, you will actually see drastic performance decreases because the system has to use virtual memory for the key buffer.
  • my.cnf配置(转)

    2007-09-24 13:58:43Digest 4

    本文中的配置都是从《MySQL5权威指南(3rd)》中摘抄出来的,个人认为对于使用MySQL十分有用。放在此处方便自己随时查阅,也希望对其他朋友有所助益。(2007.05.30最后更新)

    mysqld程序--目录和文件
    basedir = path  使用给定目录作为根目录(安装目录)。
    character-sets-dir = path  给出存放着字符集的目录。
    datadir = path  从给定目录读取数据库文件。
    pid-file = filename  为mysqld程序指定一个存放进程ID的文件(仅适用于UNIX/Linux系统); Init-V脚本需要使用这个文件里的进程ID结束mysqld进程。
    socket = filename  为MySQL客户程序与服务器之间的本地通信指定一个套接字文件(仅适用于UNIX/Linux系统; 默认设置一般是/var/lib/mysql/mysql.sock文件)。
        在Windows环境下,如果MySQL客户与服务器是通过命名管道进行通信的,--sock选项给出的将是该命名管道的名字(默认设置是MySQL)。
    lower_case_table_name = 1/0  新目录和数据表的名字是否只允许使用小写字母; 这个选项在Windows环境下的默认设置是1(只允许使用小写字母)。

    mysqld程序--语言设置
    character-sets-server = name  新数据库或数据表的默认字符集。为了与MySQL的早期版本保持兼容,这个字符集也可以用--default-character-set选项给出; 但这个选项已经显得有点过时了。
    collation-server = name  新数据库或数据表的默认排序方式。
    lanuage = name  用指定的语言显示出错信息。

    mysqld程序--通信、网络、信息安全
    enable-named-pipes  允许Windows 2000/XP环境下的客户和服务器使用命名管道(named pipe)进行通信。这个命名管道的默认名字是MySQL,但可以用--socket选项来改变。
    local-infile [=0]  允许/禁止使用LOAD DATA LOCAL语句来处理本地文件。
    myisam-recover [=opt1, opt2, ...]  在启动时自动修复所有受损的MyISAM数据表。这个选项的可取值有4种:DEFAULT、BACKUP、QUICK和FORCE; 它们与myisamchk程序的同名选项作用相同。
    old-passwords  使用MySQL 3.23和4.0版本中的老算法来加密mysql数据库里的密码(默认使用MySQL 4.1版本开始引入的新加密算法)。
    port = n  为MySQL程序指定一个TCP/IP通信端口(通常是3306端口)。
    safe-user-create  只有在mysql.user数据库表上拥有INSERT权限的用户才能使用GRANT命令; 这是一种双保险机制(此用户还必须具备GRANT权限才能执行GRANT命令)。
    shared-memory  允许使用内存(shared memory)进行通信(仅适用于Windows)。
    shared-memory-base-name = name  给共享内存块起一个名字(默认的名字是MySQL)。
    skip-grant-tables  不使用mysql数据库里的信息来进行访问控制(警告:这将允许用户任何用户去修改任何数据库)。
    skip-host-cache  不使用高速缓存区来存放主机名和IP地址的对应关系。
    skip-name-resovle  不把IP地址解析为主机名; 与访问控制(mysql.user数据表)有关的检查全部通过IP地址行进。
    skip-networking  只允许通过一个套接字文件(Unix/Linux系统)或通过命名管道(Windows系统)进行本地连接,不允许ICP/IP连接; 这提高了安全性,但阻断了来自网络的外部连接和所有的Java客户程序(Java客户即使在本地连接里也使用TCP/IP)。
    user = name  mysqld程序在启动后将在给定UNIX/Linux账户下执行; mysqld必须从root账户启动才能在启动后切换到另一个账户下执行; mysqld_safe脚本将默认使用--user=mysql选项来启动mysqld程序。

    mysqld程序--内存管理、优化、查询缓存区
    bulk_insert_buffer_size = n  为一次插入多条新记录的INSERT命令分配的缓存区长度(默认设置是8M)。
    key_buffer_size = n  用来存放索引区块的RMA值(默认设置是8M)。
    join_buffer_size = n  在参加JOIN操作的数据列没有索引时为JOIN操作分配的缓存区长度(默认设置是128K)。
    max_heap_table_size = n  HEAP数据表的最大长度(默认设置是16M); 超过这个长度的HEAP数据表将被存入一个临时文件而不是驻留在内存里。
    max_connections = n  MySQL服务器同时处理的数据库连接的最大数量(默认设置是100)。
    query_cache_limit = n  允许临时存放在查询缓存区里的查询结果的最大长度(默认设置是1M)。
    query_cache_size = n  查询缓存区的最大长度(默认设置是0,不开辟查询缓存区)。
    query_cache_type = 0/1/2  查询缓存区的工作模式:0, 禁用查询缓存区; 1,启用查询缓存区(默认设置); 2,"按需分配"模式,只响应SELECT SQL_CACHE命令。
    read_buffer_size = n  为从数据表顺序读取数据的读操作保留的缓存区的长度(默认设置是128KB); 这个选项的设置值在必要时可以用SQL命令SET SESSION read_buffer_size = n命令加以改变。
    read_rnd_buffer_size = n  类似于read_buffer_size选项,但针对的是按某种特定顺序(比如使用了ORDER BY子句的查询)输出的查询结果(默认设置是256K)。
    sore_buffer = n  为排序操作分配的缓存区的长度(默认设置是2M); 如果这个缓存区太小,则必须创建一个临时文件来进行排序。
    table_cache = n  同时打开的数据表的数量(默认设置是64)。
    tmp_table_size = n  临时HEAP数据表的最大长度(默认设置是32M); 超过这个长度的临时数据表将被转换为MyISAM数据表并存入一个临时文件。

    mysqld程序--日志
    log [= file]  把所有的连接以及所有的SQL命令记入日志(通用查询日志); 如果没有给出file参数,MySQL将在数据库目录里创建一个hostname.log文件作为这种日志文件(hostname是服务器的主机名)。
    log-slow-queries [= file]  把执行用时超过long_query_time变量值的查询命令记入日志(慢查询日志); 如果没有给出file参数,MySQL将在数据库目录里创建一个hostname-slow.log文件作为这种日志文件(hostname是服务器主机 名)。
    long_query_time = n  慢查询的执行用时上限(默认设置是10s)。
    long_queries_not_using_indexs  把慢查询以及执行时没有使用索引的查询命令全都记入日志(其余同--log-slow-queries选项)。
    log-bin [= filename]  把对数据进行修改的所有SQL命令(也就是INSERT、UPDATE和DELETE命令)以二进制格式记入日志(二进制变更日志,binary update log)。这种日志的文件名是filename.n或默认的hostname.n,其中n是一个6位数字的整数(日志文件按顺序编号)。
    log-bin-index = filename  二进制日志功能的索引文件名。在默认情况下,这个索引文件与二进制日志文件的名字相同,但后缀名是.index而不是.nnnnnn。
    max_binlog_size = n  二进制日志文件的最大长度(默认设置是1GB)。在前一个二进制日志文件里的信息量超过这个最大长度之前,MySQL服务器会自动提供一个新的二进制日志文件接续上。
    binlog-do-db = dbname  只把给定数据库里的变化情况记入二进制日志文件,其他数据库里的变化情况不记载。如果需要记载多个数据库里的变化情况,就必须在配置文件使用多个本选项来设置,每个数据库一行。
    binlog-ignore-db = dbname  不把给定数据库里的变化情况记入二进制日志文件。
    sync_binlog = n  每经过n次日志写操作就把日志文件写入硬盘一次(对日志信息进行一次同步)。n=1是最安全的做法,但效率最低。默认设置是n=0,意思是由操作系统来负责二进制日志文件的同步工作。
    log-update [= file]  记载出错情况的日志文件名(出错日志)。这种日志功能无法禁用。如果没有给出file参数,MySQL会使用hostname.err作为种日志文件的名字。

    mysqld程序--镜像(主控镜像服务器)
    server-id = n  给服务器分配一个独一无二的ID编号; n的取值范围是1~2的32次方启用二进制日志功能。
    log-bin = name  启用二进制日志功能。这种日志的文件名是filename.n或默认的hostname.n,其中的n是一个6位数字的整数(日志文件顺序编号)。
    binlog-do/ignore-db = dbname  只把给定数据库里的变化情况记入二进制日志文件/不把给定的数据库里的变化记入二进制日志文件。

    mysqld程序--镜像(从属镜像服务器)
    server-id = n  给服务器分配一个唯一的ID编号
    log-slave-updates  启用从属服务器上的日志功能,使这台计算机可以用来构成一个镜像链(A->B->C)。
    master-host = hostname  主控服务器的主机名或IP地址。如果从属服务器上存在mater.info文件(镜像关系定义文件),它将忽略此选项。
    master-user = replicusername  从属服务器用来连接主控服务器的用户名。如果从属服务器上存在mater.info文件,它将忽略此选项。
    master-password = passwd  从属服务器用来连接主控服务器的密码。如果从属服务器上存在mater.info文件,它将忽略此选项。
    master-port = n  从属服务器用来连接主控服务器的TCP/IP端口(默认设置是3306端口)。
    master-connect-retry = n  如果与主控服务器的连接没有成功,则等待n秒(s)后再进行管理方式(默认设置是60s)。如果从属服务器存在mater.info文件,
        它将忽略此选项。
    master-ssl-xxx = xxx  对主、从服务器之间的SSL通信进行配置。
    read-only = 0/1  0: 允许从属服务器独立地执行SQL命令(默认设置); 1: 从属服务器只能执行来自主控服务器的SQL命令。
    read-log-purge = 0/1  1: 把处理完的SQL命令立刻从中继日志文件里删除(默认设置); 0: 不把处理完的SQL命令立刻从中继日志文件里删除。
    replicate-do-table = dbname.tablename  与--replicate-do-table选项的含义和用法相同,但数据库和数据库表名字里允许出现通配符"%"
        (例如: test%.%--对名字以"test"开头的所有数据库里的所以数据库表进行镜像处理)。
    replicate-do-db = name  只对这个数据库进行镜像处理。
    replicate-ignore-table = dbname.tablename  不对这个数据表进行镜像处理。
    replicate-wild-ignore-table = dbn.tablen  不对这些数据表进行镜像处理。
    replicate-ignore-db = dbname  不对这个数据库进行镜像处理。
    replicate-rewrite-db = db1name > db2name  把主控数据库上的db1name数据库镜像处理为从属服务器上的db2name数据库。
    report-host = hostname  从属服务器的主机名; 这项信息只与SHOW SLAVE HOSTS命令有关--主控服务器可以用这条命令生成一份从属服务器的名单。
    slave-compressed-protocol = 1  主、从服务器使用压缩格式进行通信--如果它们都支持这么做的话。
    slave-skip-errors = n1, n2, ...或all  即使发生出错代码为n1、n2等的错误,镜像处理工作也继续进行(即不管发生什么错误,镜像处理工作也继续进行)。
        如果配置得当,从属服务器不应该在执行SQL命令时发生错误(在主控服务器上执行出错的SQL命令不会被发送到从属服务器上做镜像处理); 如果不使用
        slave-skip-errors选项,从属服务器上的镜像工作就可能国为发生错误而中断,中断后需要有人工参与才能继续进行。

    mysqld--InnoDB--基本设置、表空间文件
    skip-innodb  不加载InnoDB数据表驱动程序--如果用不着InnoDB数据表,可以用这个选项节省一些内存。
    innodb-file-per-table  为每一个新数据表创建一个表空间文件而不是把数据表都集中保存在中央表空间里(后者是默认设置)。该选项始见于MySQL 4.1。
    innodb-open-file = n  InnoDB数据表驱动程序最多可以同时打开的文件数(默认设置是300)。如果使用了innodb-file-per-table选项并且需要同时打开很多
        数据表的话,这个数字很可能需要加大。
    innodb_data_home_dir = p  InnoDB主目录,所有与InnoDB数据表有关的目录或文件路径都相对于这个路径。在默认的情况下,这个主目录就是MySQL的数据目录。
    innodb_data_file_path = ts  用来容纳InnoDB为数据表的表空间: 可能涉及一个以上的文件; 每一个表空间文件的最大长度都必须以字节(B)、兆字节(MB)或
        千兆字节(GB)为单位给出; 表空间文件的名字必须以分号隔开; 最后一个表空间文件还可以带一个autoextend属性和一个最大长度(max:n)。
        例如,ibdata1:1G; ibdata2:1G:autoextend:max:2G的意思是: 表空间文件ibdata1的最大长度是1GB,ibdata2的最大长度也是1G,但允许它扩充到2GB。
        除文件名外,还可以用硬盘分区的设置名来定义表空间,此时必须给表空间的最大初始长度值加上newraw关键字做后缀,给表空间的最大扩充长度值加上
        raw关键字做后缀(例如/dev/hdb1:20Gnewraw或/dev/hdb1:20Graw); MySQL 4.0及更高版本的默认设置是ibdata1:10M:autoextend。
    innodb_autoextend_increment = n  带有autoextend属性的表空间文件每次加大多少兆字节(默认设置是8MB)。这个属性不涉及具体的数据表文件,那些文件的
        增大速度相对是比较小的。
    innodb_lock_wait_timeout = n  如果某个事务在等待n秒(s)后还没有获得所需要的资源,就使用ROLLBACK命令放弃这个事务。这项设置对于发现和处理未能被
        InnoDB数据表驱动程序识别出来的死锁条件有着重要的意义。这个选项的默认设置是50s。
    innodb_fast_shutdown 0/1  是否以最快的速度关闭InnoDB,默认设置是1,意思是不把缓存在INSERT缓存区的数据写入数据表,那些数据将在MySQL服务器下次
        启动时再写入(这么做没有什么风险,因为INSERT缓存区是表空间的一个组成部分,数据不会丢失)。把这个选项设置为0反面危险,因为在计算机关闭时,
        InnoDB驱动程序很可能没有足够的时间完成它的数据同步工作,操作系统也许会在它完成数据同步工作之前强行结束InnoDB,而这会导致数据不完整。

    mysqld程序--InnoDB--日志
    innodb_log_group_home_dir = p  用来存放InnoDB日志文件的目录路径(如ib_logfile0、ib_logfile1等)。在默认的情况下,InnoDB驱动程序将使用MySQL数据目
        录作为自己保存日志文件的位置。   
    innodb_log_files_in_group = n  使用多少个日志文件(默认设置是2)。InnoDB数据表驱动程序将以轮转方式依次填写这些文件; 当所有的日志文件都写满以后,
        之后的日志信息将写入第一个日志文件的最大长度(默认设置是5MB)。这个长度必须以MB(兆字节)或GB(千兆字节)为单位进行设置。
    innodb_flush_log_at_trx_commit = 0/1/2  这个选项决定着什么时候把日志信息写入日志文件以及什么时候把这些文件物理地写(术语称为"同步")到硬盘上。
        设置值0的意思是每隔一秒写一次日志并进行同步,这可以减少硬盘写操作次数,但可能造成数据丢失; 设置值1(设置设置)的意思是在每执行完一条COMMIT
        命令就写一次日志并进行同步,这可以防止数据丢失,但硬盘写操作可能会很频繁; 设置值2是一般折衷的办法,即每执行完一条COMMIT命令写一次日志,
        每隔一秒进行一次同步。
    innodb_flush_method = x  InnoDB日志文件的同步办法(仅适用于UNIX/Linux系统)。这个选项的可取值有两种: fdatasync,用fsync()函数进行同步; O_DSYNC,
        用O_SYNC()函数进行同步。
    innodb_log_archive = 1  启用InnoDB驱动程序的archive(档案)日志功能,把日志信息写入ib_arch_log_n文件。启用这种日志功能在InnoDB与MySQL一起使用时没有
        多大意义(启用MySQL服务器的二进制日志功能就足够用了)。

    mysqld程序--InnoDB--缓存区的设置和优化
    innodb_log_buffer_pool_size = n  为InnoDB数据表及其索引而保留的RAM内存量(默认设置是8MB)。这个参数对速度有着相当大的影响,如果计算机上只运行有
        MySQL/InnoDB数据库服务器,就应该把全部内存的80%用于这个用途。
    innodb_log_buffer_size = n  事务日志文件写操作缓存区的最大长度(默认设置是1MB)。
    innodb_additional_men_pool_size = n  为用于内部管理的各种数据结构分配的缓存区最大长度(默认设置是1MB)。
    innodb_file_io_threads = n  I/O操作(硬盘写操作)的最大线程个数(默认设置是4)。
    innodb_thread_concurrency = n  InnoDB驱动程序能够同时使用的最大线程个数(默认设置是8)。

    mysqld程序--其它选项
    bind-address = ipaddr  MySQL服务器的IP地址。如果MySQL服务器所在的计算机有多个IP地址,这个选项将非常重要。
    default-storage-engine = type  新数据表的默认数据表类型(默认设置是MyISAM)。这项设置还可以通过--default-table-type选项来设置。
    default-timezone = name  为MySQL服务器设置一个地理时区(如果它与本地计算机的地理时区不一样)。
    ft_min_word_len = n  全文索引的最小单词长度工。这个选项的默认设置是4,意思是在创建全文索引时不考虑那些由3个或更少的字符构建单词。
    Max-allowed-packet = n  客户与服务器之间交换的数据包的最大长度,这个数字至少应该大于客户程序将要处理的最大BLOB块的长度。这个选项的默认设置是1MB。
    Sql-mode = model1, mode2, ...  MySQL将运行在哪一种SQL模式下。这个选项的作用是让MySQL与其他的数据库系统保持最大程度的兼容。这个选项的可取值包括
        ansi、db2、oracle、no_zero_date、pipes_as_concat。

    注意:如果在配置文件里给出的某个选项是mysqld无法识别的(如,因为犯了一个愚蠢的打字错误),MySQL服务器将不启动。
  • 在win2003下MySQL数据库每天自动备份

    2007-09-24 13:48:15Digest 4

    来源/作者:中国论坛网 houfa

            终于让服务器每天早上备份一次 MySQL 数据库并自动打包,同时删除 5 天前的备份文件. 分享如下.

    1. 环境: windows server 2003 + Apache 2.0 + PHP5 + MySQL 4.0.26 .

    2. 假设 PHP 安装目录为 D:/php ,MySQL 安装目录为 D:/mysql.

    3. 在 D:/php 下建立目录 WinRAR, 把你 winrar 安装目录下的 WinRAR.exe 和 RARReg.KEY 复制到 D:/php/WinRAR .

    4. D:/php 下建立文件 mysql_backup.php:

     

    /*/////////////////////////
    #FileName: mysql_backup.php
    #Author: faisun
    #Website: http://www.softpure.com
    ////////////////////////*/
    //保存目录,路径要用反斜杠.您需要手动建立它.
    $store_folder = 'D:\databse_backup';
    //用户名和密码
    //该帐号须有操作[所有]的数据库及FILE的权限
    //否则有些数据库不能备份.
    $db_username = "root";
    $db_password = "";
    $time=time();
    $nowdir = "$store_folder\\".date("Ymd",$time)."";
    if(file_exists("$nowdir.rar")) die("File exists.\n");
    @mkdir($nowdir);
    mysql_connect("localhost","$db_username","$db_password");
    $query=mysql_list_dbs();
    while($result=mysql_fetch_array($query)){
    system (dirname(__FILE__).'\..\mysql\bin\mysqldump --opt '."$result[Database]
    -u{$db_username} ".($db_password?"-p{$db_password}":"")." >
    $nowdir\\$result[Database].sql");
    echo "dumping database `$result[Database]`...\n";
    }
    echo "\nWinrar loading...\n";
    system( dirname(__FILE__)."\\WinRAR\\WinRAR.exe a -ep1 -r -o+ -m5 -df \"$nowdir.rar\"
    "$nowdir\" " );
    //删除 5 天前的文件
    @unlink("$store_folder\\".date("Ymd",$time-86400*5).".rar");
    echo "\nOK!\n";
    >

    5. D:/php 下建立文件 mysql_backup.bat,内容只有一句:

     

    php.exe mysql_backup.php

    6. 双击该 bat 文件运行,如果能备份了,OK,下一步添加任务计划.

    7. 把 D:/php/mysql_backup 添加到任务计划,时间选每天. 根据服务器的监测结果,每天早上 5-8 时为流量低峰期. 由于 5-7 时有些数据库的清理工作,可以把时间定在了早上 8 点整.

  • LAMP 系统性能调优

    2007-09-24 13:48:15Digest 4

    LAMP 系统性能调优,第 3 部分: MySQL 服务器调优

    利用服务器的几个调优技巧,让 MySQL 服务器飞速运行

    developerWorks
    文档选项

    未显示需要 JavaScript 的文档选项

    将此页作为电子邮件发送

    将此页作为电子邮件发送



    级别: 中级

    Sean A. Walberg (sean@ertw.com), 高级网络工程师

    2007 年 7 月 30 日

    如今,开发人员不断地开发和部署使用 LAMP(Linux®、Apache、MySQL 和 PHP/Perl)架构的应用程序。但是,服务器管理员常常对应用程序本身没有什么控制能力,因为应用程序是别人编写的。这份 共三部分的系列文章 将讨论许多服务器配置问题,这些配置会影响应用程序的性能。本文是本系列文章的第三部分,也是最后一部分,将重点讨论为实现最高效率而对数据库层进行的调优。

    关于 MySQL 调优

    有 3 种方法可以加快 MySQL 服务器的运行速度,效率从低到高依次为:

    1. 替换有问题的硬件。
    2. 对 MySQL 进程的设置进行调优。
    3. 对查询进行优化。
    迁移到 DB2
    您正在寻找一种干净利落、无成本的方法用来从 MySQL 迁移到 IBM® DB2® 吗?“从 MySQL 或 PostgreSQL 迁移到 DB2 Express-C” 介绍了如何使用文中提供的迁移工具来简单地实现这种转换。可以 下载 免费的 DB2 Express-C 并开始体验。

    替换有问题的硬件通常是我们的第一考虑,主要原因是数据库会占用大量资源。不过这种解决方案也就仅限于此了。实际上,您通常可以让中央处理器(CPU)或磁盘速度加倍,也可以让内存增大 4 到 8 倍。

    第二种方法是对 MySQL 服务器(也称为 mysqld)进行调优。对这个进程进行调优意味着适当地分配内存,并让 mysqld 了解将会承受何种类型的负载。加快磁盘运行速度不如减少所需的磁盘访问次数。类似地,确保 MySQL 进程正确操作就意味着它花费在服务查询上的时间要多于花费在处理后台任务(如处理临时磁盘表或打开和关闭文件)上的时间。对 mysqld 进行调优是本文的重点。

    最好的方法是确保查询已经进行了优化。这意味着对表应用了适当的索引,查询是按照可以充分利用 MySQL 功能的方式来编写的。尽管本文并没有包含查询调优方面的内容(很多著作中已经针对这个主题进行了探讨),不过它会配置 mysqld 来报告可能需要进行调优的查询。

    虽然已经为这些任务指派了次序,但是仍然要注意硬件和 mysqld 的设置以利于适当地调优查询。机器速度慢也就罢了,我曾经见过速度很快的机器在运行设计良好的查询时由于负载过重而失败,因为 mysqld 被大量繁忙的工作所占用而不能服务查询。





    回页首


    记录慢速查询

    在一个 SQL 服务器中,数据表都是保存在磁盘上的。索引为服务器提供了一种在表中查找特定数据行的方法,而不用搜索整个表。当必须要搜索整个表时,就称为表扫描。通常来说,您可能只希望获得表中数据的一个子集,因此全表扫描会浪费大量的磁盘 I/O,因此也就会浪费大量时间。当必须对数据进行连接时,这个问题就更加复杂了,因为必须要对连接两端的多行数据进行比较。

    当 然,表扫描并不总是会带来问题;有时读取整个表反而会比从中挑选出一部分数据更加有效(服务器进程中查询规划器用来作出这些决定)。如果索引的使用效率很 低,或者根本就不能使用索引,则会减慢查询速度,而且随着服务器上的负载和表大小的增加,这个问题会变得更加显著。执行时间超过给定时间范围的查询就称为慢速查询

    您可以配置 mysqld 将这些慢速查询记录到适当命名的慢速查询日志中。管理员然后会查看这个日志来帮助他们确定应用程序中有哪些部分需要进一步调查。清单 1 给出了要启用慢速查询日志需要在 my.cnf 中所做的配置。


    清单 1. 启用 MySQL 慢速查询日志
                    
    [mysqld]
    ; enable the slow query log, default 10 seconds
    log-slow-queries
    ; log queries taking longer than 5 seconds
    long_query_time = 5
    ; log queries that don't use indexes even if they take less than long_query_time
    ; MySQL 4.1 and newer only
    log-queries-not-using-indexes

    这三个设置一起使用,可以记录执行时间超过 5 秒和没有使用索引的查询。请注意有关 log-queries-not-using-indexes 的警告:您必须使用 MySQL 4.1 或更高版本。慢速查询日志都保存在 MySQL 数据目录中,名为 hostname-slow.log。如果希望使用一个不同的名字或路径,可以在 my.cnf 中使用 log-slow-queries = /new/path/to/file 实现此目的。

    阅读慢速查询日志最好是通过 mysqldumpslow 命令进行。指定日志文件的路径,就可以看到一个慢速查询的排序后的列表,并且还显示了它们在日志文件中出现的次数。一个非常有用的特性是 mysqldumpslow 在比较结果之前,会删除任何用户指定的数据,因此对同一个查询的不同调用被计为一次;这可以帮助找出需要工作量最多的查询。





    回页首


    对查询进行缓存

    很多 LAMP 应用程序都严重依赖于数据库,但却会反复执行相同的查询。每次执行查询时,数据库都必须要执行相同的工作 —— 对查询进行分析,确定如何执行查询,从磁盘中加载信息,然后将结果返回给客户机。MySQL 有一个特性称为查询缓存,它将(后面会用到的)查询结果保存在内存中。在很多情况下,这会极大地提高性能。不过,问题是查询缓存在默认情况下是禁用的。

    query_cache_size = 32M 添加到 /etc/my.conf 中可以启用 32MB 的查询缓存。

    监视查询缓存

    在启用查询缓存之后,重要的是要理解它是否得到了有效的使用。MySQL 有几个可以查看的变量,可以用来了解缓存中的情况。清单 2 给出了缓存的状态。


    清单 2. 显示查询缓存的统计信息
                    
    mysql> SHOW STATUS LIKE 'qcache%';
    +-------------------------+------------+
    | Variable_name | Value |
    +-------------------------+------------+
    | Qcache_free_blocks | 5216 |
    | Qcache_free_memory | 14640664 |
    | Qcache_hits | 2581646882 |
    | Qcache_inserts | 360210964 |
    | Qcache_lowmem_prunes | 281680433 |
    | Qcache_not_cached | 79740667 |
    | Qcache_queries_in_cache | 16927 |
    | Qcache_total_blocks | 47042 |
    +-------------------------+------------+
    8 rows in set (0.00 sec)

    这些项的解释如表 1 所示。


    表 1. MySQL 查询缓存变量
    变量名说明
    Qcache_free_blocks 缓存中相邻内存块的个数。数目大说明可能有碎片。FLUSH QUERY CACHE 会对缓存中的碎片进行整理,从而得到一个空闲块。
    Qcache_free_memory 缓存中的空闲内存。
    Qcache_hits 每次查询在缓存中命中时就增大。
    Qcache_inserts 每次插入一个查询时就增大。命中次数除以插入次数就是不中比率;用 1 减去这个值就是命中率。在上面这个例子中,大约有 87% 的查询都在缓存中命中。
    Qcache_lowmem_prunes 缓存出现内存不足并且必须要进行清理以便为更多查询提供空间的次数。这个数字最好长时间来看;如果这个数字在不断增长,就表示可能碎片非常严重,或者内存很少。(上面的 free_blocksfree_memory 可以告诉您属于哪种情况)。
    Qcache_not_cached 不适合进行缓存的查询的数量,通常是由于这些查询不是 SELECT 语句。
    Qcache_queries_in_cache 当前缓存的查询(和响应)的数量。
    Qcache_total_blocks 缓存中块的数量。

    通常,间隔几秒显示这些变量就可以看出区别,这可以帮助确定缓存是否正在有效地使用。运行 FLUSH STATUS 可以重置一些计数器,如果服务器已经运行了一段时间,这会非常有帮助。

    使用非常大的查询缓存,期望可以缓存所有东西,这种想法非常诱人。由于 mysqld 必须要对缓存进行维护,例如当内存变得很低时执行剪除,因此服务器可能会在试图管理缓存时而陷入困境。作为一条规则,如果 FLUSH QUERY CACHE 占用了很长时间,那就说明缓存太大了。





    回页首


    强制限制

    您可以在 mysqld 中强制一些限制来确保系统负载不会导致资源耗尽的情况出现。清单 3 给出了 my.cnf 中与资源有关的一些重要设置。


    清单 3. MySQL 资源设置
                    
    set-variable=max_connections=500
    set-variable=wait_timeout=10
    max_connect_errors = 100

    连接最大个数是在第一行中进行管理的。与 Apache 中的 MaxClients 类似,其想法是确保只建立服务允许数目的连接。要确定服务器上目前建立过的最大连接数,请执行 SHOW STATUS LIKE 'max_used_connections'

    第 2 行告诉 mysqld 终止所有空闲时间超过 10 秒的连接。在 LAMP 应用程序中,连接数据库的时间通常就是 Web 服务器处理请求所花费的时间。有时候,如果负载过重,连接会挂起,并且会占用连接表空间。如果有多个交互用户或使用了到数据库的持久连接,那么将这个值设 低一点并不可取!

    最后一行是一个安全的方法。如果一个主机在连接到服务器时有问题,并重试很多次后放弃,那么这个主机就会被锁定,直到 FLUSH HOSTS 之后才能运行。默认情况下,10 次失败就足以导致锁定了。将这个值修改为 100 会给服务器足够的时间来从问题中恢复。如果重试 100 次都无法建立连接,那么使用再高的值也不会有太多帮助,可能它根本就无法连接。





    回页首


    缓冲区和缓存

    MySQL 支持超过 100 个的可调节设置;但是幸运的是,掌握少数几个就可以满足大部分需要。查找这些设置的正确值可以通过 SHOW STATUS 命令查看状态变量,从中可以确定 mysqld 的运作情况是否符合我们的预期。给缓冲区和缓存分配的内存不能超过系统中的现有内存,因此调优通常都需要进行一些妥协。

    MySQL 可调节设置可以应用于整个 mysqld 进程,也可以应用于单个客户机会话。

    服务器端的设置

    每个表都可以表示为磁盘上的一个文件,必须先打开,后读取。为了加快从文件中读取数据的过程,mysqld 对这些打开文件进行了缓存,其最大数目由 /etc/mysqld.conf 中的 table_cache 指定。清单 4 给出了显示与打开表有关的活动的方式。


    清单 4. 显示打开表的活动
                    
    mysql> SHOW STATUS LIKE 'open%tables';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | Open_tables | 5000 |
    | Opened_tables | 195 |
    +---------------+-------+
    2 rows in set (0.00 sec)

    清单 4 说明目前有 5,000 个表是打开的,有 195 个表需要打开,因为现在缓存中已经没有可用文件描述符了(由于统计信息在前面已经清除了,因此可能会存在 5,000 个打开表中只有 195 个打开记录的情况)。如果 Opened_tables 随着重新运行 SHOW STATUS 命令快速增加,就说明缓存命中率不够。如果 Open_tablestable_cache 设置小很多,就说明该值太大了(不过有空间可以增长总不是什么坏事)。例如,使用 table_cache = 5000 可以调整表的缓存。

    与表的缓存类似,对于线程来说也有一个缓存。 mysqld 在接收连接时会根据需要生成线程。在一个连接变化很快的繁忙服务器上,对线程进行缓存便于以后使用可以加快最初的连接。

    清单 5 显示如何确定是否缓存了足够的线程。


    清单 5. 显示线程使用统计信息
                    
    mysql> SHOW STATUS LIKE 'threads%';
    +-------------------+--------+
    | Variable_name | Value |
    +-------------------+--------+
    | Threads_cached | 27 |
    | Threads_connected | 15 |
    | Threads_created | 838610 |
    | Threads_running | 3 |
    +-------------------+--------+
    4 rows in set (0.00 sec)

    此处重要的值是 Threads_created,每次 mysqld 需要创建一个新线程时,这个值都会增加。如果这个数字在连续执行 SHOW STATUS 命令时快速增加,就应该尝试增大线程缓存。例如,可以在 my.cnf 中使用 thread_cache = 40 来实现此目的。

    关键字缓冲区保存了 MyISAM 表的索引块。理想情况下,对于这些块的请求应该来自于内存,而不是来自于磁盘。清单 6 显示了如何确定有多少块是从磁盘中读取的,以及有多少块是从内存中读取的。


    清单 6. 确定关键字效率
                    
    mysql> show status like '%key_read%';
    +-------------------+-----------+
    | Variable_name | Value |
    +-------------------+-----------+
    | Key_read_requests | 163554268 |
    | Key_reads | 98247 |
    +-------------------+-----------+
    2 rows in set (0.00 sec)

    Key_reads 代表命中磁盘的请求个数, Key_read_requests 是总数。命中磁盘的读请求数除以读请求总数就是不中比率 —— 在本例中每 1,000 个请求,大约有 0.6 个没有命中内存。如果每 1,000 个请求中命中磁盘的数目超过 1 个,就应该考虑增大关键字缓冲区了。例如,key_buffer = 384M 会将缓冲区设置为 384MB。

    临时表可以在更高级的查询中使用,其中数据在进一步进行处理(例如 GROUP BY 字句)之前,都必须先保存到临时表中;理想情况下,在内存中创建临时表。但是如果临时表变得太大,就需要写入磁盘中。清单 7 给出了与临时表创建有关的统计信息。


    清单 7. 确定临时表的使用
                    
    mysql> SHOW STATUS LIKE 'created_tmp%';
    +-------------------------+-------+
    | Variable_name | Value |
    +-------------------------+-------+
    | Created_tmp_disk_tables | 30660 |
    | Created_tmp_files | 2 |
    | Created_tmp_tables | 32912 |
    +-------------------------+-------+
    3 rows in set (0.00 sec)

    每次使用临时表都会增大 Created_tmp_tables;基于磁盘的表也会增大 Created_tmp_disk_tables。对于这个比率,并没有什么严格的规则,因为这依赖于所涉及的查询。长时间观察 Created_tmp_disk_tables 会显示所创建的磁盘表的比率,您可以确定设置的效率。 tmp_table_sizemax_heap_table_size 都可以控制临时表的最大大小,因此请确保在 my.cnf 中对这两个值都进行了设置。

    每个会话的设置

    下面这些设置针对于每个会话。在设置这些数字时要十分谨慎,因为它们在乘以可能存在的连接数时候,这些选项表示大量的内存!您可以通过代码修改会话中的这些数字,或者在 my.cnf 中为所有会话修改这些设置。

    当 MySQL 必须要进行排序时,就会在从磁盘上读取数据时分配一个排序缓冲区来存放这些数据行。如果要排序的数据太大,那么数据就必须保存到磁盘上的临时文件中,并再次进行排序。如果 sort_merge_passes 状态变量很大,这就指示了磁盘的活动情况。清单 8 给出了一些与排序相关的状态计数器信息。


    清单 8. 显示排序统计信息
                    
    mysql> SHOW STATUS LIKE "sort%";
    +-------------------+---------+
    | Variable_name | Value |
    +-------------------+---------+
    | Sort_merge_passes | 1 |
    | Sort_range | 79192 |
    | Sort_rows | 2066532 |
    | Sort_scan | 44006 |
    +-------------------+---------+
    4 rows in set (0.00 sec)

    如果 sort_merge_passes 很大,就表示需要注意 sort_buffer_size。例如, sort_buffer_size = 4M 将排序缓冲区设置为 4MB。

    MySQL 也会分配一些内存来读取表。理想情况下,索引提供了足够多的信息,可以只读入所需要的行,但是有时候查询(设计不佳或数据本性使然)需要读取表中大量数据。要理解这种行为,需要知道运行了多少个 SELECT 语句,以及需要读取表中的下一行数据的次数(而不是通过索引直接访问)。实现这种功能的命令如清单 9 所示。


    清单 9. 确定表扫描比率
                    
    mysql> SHOW STATUS LIKE "com_select";
    +---------------+--------+
    | Variable_name | Value |
    +---------------+--------+
    | Com_select | 318243 |
    +---------------+--------+
    1 row in set (0.00 sec)

    mysql> SHOW STATUS LIKE "handler_read_rnd_next";
    +-----------------------+-----------+
    | Variable_name | Value |
    +-----------------------+-----------+
    | Handler_read_rnd_next | 165959471 |
    +-----------------------+-----------+
    1 row in set (0.00 sec)

    Handler_read_rnd_next / Com_select 得出了表扫描比率 —— 在本例中是 521:1。如果该值超过 4000,就应该查看 read_buffer_size,例如 read_buffer_size = 4M。如果这个数字超过了 8M,就应该与开发人员讨论一下对这些查询进行调优了!





    回页首


    3 个必不可少的工具

    尽管在了解具体设置时,SHOW STATUS 命令会非常有用,但是您还需要一些工具来解释 mysqld 所提供的大量数据。我发现有 3 个工具是必不可少的;在 参考资料 一节中您可以找到相应的链接。

    大部分系统管理员都非常熟悉 top 命令,它为任务所消耗的 CPU 和内存提供了一个不断更新的视图。 mytoptop 进行了仿真;它为所有连接上的客户机以及它们正在运行的查询提供了一个视图。mytop 还提供了一个有关关键字缓冲区和查询缓存效率的实时数据和历史数据,以及有关正在运行的查询的统计信息。这是一个很有用的工具,可以查看系统中(比如 10 秒钟之内)的状况,您可以获得有关服务器健康信息的视图,并显示导致问题的任何连接。

    mysqlard 是一个连接到 MySQL 服务器上的守护程序,负责每 5 分钟搜集一次数据,并将它们存储到后台的一个 Round Robin Database 中。有一个 Web 页面会显示这些数据,例如表缓存的使用情况、关键字效率、连接上的客户机以及临时表的使用情况。尽管 mytop 提供了服务器健康信息的快照,但是 mysqlard 则提供了长期的健康信息。作为奖励,mysqlard 使用自己搜集到的一些信息针对如何对服务器进行调优给出一些建议。

    搜集 SHOW STATUS 信息的另外一个工具是 mysqlreport。其报告要远比 mysqlard 更加复杂,因为需要对服务器的每个方面都进行分析。这是对服务器进行调优的一个非常好的工具,因为它对状态变量进行适当计算来帮助确定需要修正哪些问题。





    回页首


    结束语

    分享这篇文章……

    digg 将本文提交到 Digg
    del.icio.us 发布到 del.icio.us
    Slashdot 提交到 Slashdot!

    本 文介绍了对 MySQL 进行调优的一些基础知识,并对这个针对 LAMP 组件进行调优的 3 部分系列文章进行了总结。调优很大程度上需要理解组件的工作原理,确定它们是否正常工作,进行一些调整,并重新评测。每个组件 —— Linux、Apache、PHP 或 MySQL —— 都有各种各样的需求。分别理解各个组件可以帮助减少可能会导致应用程序速度变慢的瓶颈。

  • MYSQL如何记录慢查询

    2007-09-24 13:48:15Digest 5

    如何记录slow_queries

    如果数据库很慢,就需要记录一下slow_queries,然后分析一下是那些SQL语句造成数据库比较慢,这样就可以看看程序是否还可以做进一步的优化.

    在mysql 中只需要设置在my.cnf或者my.ini中加入下面两个参数就可以记录slow_query了 .

    set-variable        = log_slow_queries=e:/mysql/slowquerynew.log  //记录slow_querise的文件地址
    5T8?6e8Q*J2b$B471318set-variable        = long_query_time=1    //超过多长时间的查询就开始记录 单位为 秒

数据统计

  • 访问量: 15271
  • 日志数: 31
  • 文件数: 6
  • 建立时间: 2007-02-19
  • 更新时间: 2007-10-23

RSS订阅

Open Toolbar