mysql的优化(2)

王朝mysql·作者佚名  2005-10-22
窄屏简体版  字體: |||超大  

优化SELECT 语句和其它查询

首先,一个影响所有语句的因素:你的权限设置越复杂,你需要的开销越大。

当你用GRANT语句分配时使用简单的权限设置,这样可以让MySQL在客户端执行语句时

减小检查权限带来的开销。例如,如果你不授予任何表级或者列级的权限,服务器

就不需要检查tables_priv 和 columns_priv 表的目录,同样的,如果你不对

帐号设置资源限制,服务器就不需要进行资源计数,如果你有一个高查询列,

就值得简化授权结构来减小权限检查开销。

如果你的问题是一些特定的MySQL表达式或者函数,你可以在客户端用BENCHMARK()

函数来作计时测试,语法是:BENCHMARK(loop_count,expression).

例如:

mysql> SELECT BENCHMARK(1000000,1+1);

+------------------------+

| BENCHMARK(1000000,1+1) |

+------------------------+

| 0 |

+------------------------+

1 row in set (0.32 sec)

这个结果是在Pentium II 400MHz 的系统上得到的。这显示Mysql可以在这种系统上

0.32秒里执行1,000,000 次简单加法。

所有的MySQL函数应该都是优化过的,但是也有例外,BENCHMARK() 是个找出你的

查询是否有问题的强大工具。

EXPLAIN 语法(得到SELECT的信息)

EXPLAIN tbl_name

Or:

EXPLAIN SELECT select_options

EXPLAIN 语句可以被用作 DESCRIBE 的同义词或者可以作为得到MySQL怎样执行一个

语句的信息:

·EXPLAIN tbl_name 语法和DESCRIBE tbl_name 或者 SHOW COLUMNS FROM tbl_name

是同义的。

·当你在SELECT语句之前放上一个关键字EXPLAIN,MySQL会解释这个SELECT是怎样

执行的,提供表是如何连接和什么顺序。

本节介绍EXPLAIN的第二种用法。

通过EXPLAIN的帮助,你可以看到用索引来查找记录时你必须为表增加索引以增快

SELECT的速度。

如果你在不正确的索引用法上有问题,你应该运行ANALYZE TABLE来升级表统计,

比如 cardinality of keys, 这个会影响到optimizer的所作的选择。

你也可以看到是否optimizer 把表按照最优顺序联结,要让optimizer按照SELECT

语句里说的顺序来联结,用 SELECT STRAIGHT_JOIN 来代替SELECT。

EXPLAIN 返回一行SELECT语句中每个表的信息,表按照处理查询时MySQL读取他们

的顺序排列,MySQL使用single-sweep multi-join的方法解决所有的联结。这表示

MySQL 从第一个表读取一行,然后在第二个表里查找适配行,然后第三个表,等等。

当所有表处理完,它输出选定的列并从table列表里原路退回,直到有更多适配行

的表,就读取此表第二行并继续执行下一个表。

在MySQL4.1里,EXPLAIN 输出格式为了更好的同一些结构适应而改变,比如UNION

语句,子查询,derived tables,最值得注意的是两个新列的增加:

id 和 select_type,你用4.1之前的版本是看不到这两列的。

EXPLAIN 的每个输出行提供了一个表的信息。

估计查询的性能

大多数情况下,你可以通过计磁盘寻道次数来估计性能。对于小表,您通常可以

在一次磁盘寻道里找到那行(因为索引可能被cache了).对于大一些的表,你可以

估计出来用B-tree 索引你会需要这么多次寻道:log(row_count) / log

(index_block_length / 3 * 2 / (index_length + data_pointer_length)) + 1.

在MySQL里,一个索引块常常是1024字节,数据指针是4字节,对于一个索引占3字节

的500,000行的表,按公式可以得到log(500,000)/log(1024/3*2/(3+4)) + 1 = 4

次寻道。

这个索引需要占用的存储空间:500,000 * 7 * 3/2 = 5.2MB

(假定一个典型的索引填充率2/3), 所以大部分索引可能在内存里,而你大概只

需要一到两个访问读取数据找到需要的行。

对于写数据,你会需要4次寻道请求来找出存放新索引的位置,一般两次寻道来

更新索引并写入行。

注意前面的讨论并不表示你的程序的性能会根据 log N 慢慢衰减!只要所有东西

都被系统或者数据库cache,当表变大时只会慢一点点。当数据大到没法cache时,

就会变得很慢。要避免这个,可以增加key cache size,对于MyISAM的表,

key cache size 由系统变量 key_buffer_size 来控制。

SELECT 查询的速度

一般来说,当你想让SELECT ... WHERE 变快,第一件事就是看看你是否能加索引,

所有不同表之间的参照都应该通过索引来完成。你可以使用EXPLAIN语句来判断

SELECT 使用的是哪些索引。

一些加快MyISAM表查询的tips:

·要帮助MySQL优化查询,可以在一个表载入数据后使用ANALYZE TABLE 或者运行

myisamchk --analyze。This updates a value for each index part that

indicates the average number of rows that have the same value.

(For unique indexes, this is always 1.) MySQL will use this to decide

which index to choose when you join two tables based on a non-constant

expression. You can check the result from the table analysis by using

SHOW INDEX FROM tbl_name and examining the Cardinality value.

myisamchk --description --verbose shows index distribution information.

·按照索引分类索引和数据,使用 myisamchk --sort-index --sort-records=1

(如果你想归类索引1). This is a good way to make queries faster if you

have a unique index from which you want to read all records in order

according to the index. Note that the first time you sort a large table

this way, it may take a long time.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航