MySQL手册版本 5.0.20-MySQL优化(三)

mysql|优化

7.2.2 估算查询性能

在大多数情况下,可以通过统计磁盘搜索次数来估算查询的性能。对小表来说,通常情况下只需要搜索一次磁盘就能找到对应的记录(因为索引可能已经缓存起来了)。对大表来说,大致可以这么估算,它使用B树做索引,想要找到一条记录大概需要搜索的次数为:log(row_count) / log(index_block_length / 3 * 2 / (index_length + data_pointer_length)) + 1。

在MySQL中,一个索引块通常是1024bytes,数据指针通常是4bytes。对于一个有500,000条记录、索引长度为3bytes(medium integer)的表来说,根据上面的公式计算得到需要做 log(500,000)/log(1024/3*2/(3+4)) + 1 = 4 次搜索。

这个表的索引大概需要 500,000 * 7 * 3/2 = 5.2MB的存储空间(假定典型的索引缓冲区的2/3),因此应该会有更多的索引在内存中,并且可能只需要1到2次调用就能找到对应的记录。

对于写来说,大概需要4次(甚至更多)搜索才能找到新的索引位置,更新记录时通常需要2次搜索。

请注意,前面的讨论中并没有提到应用程序的性能会因为log N的值越大而下降。只要所有的东西都能由操作系统或者SQL服务器缓存起来,那么性能只会因为数据表越大而稍微下降。当数据越来越大之后,就不能全部放到缓存中去了,就会越来越慢了,除非应用程序是被磁盘搜索约束的(它跟随着的log N值增加而增加)。为了避免这种情况,可以在数据量增大以后也随着增大索引缓存容量。对 MyISAM 类型表来说,索引缓存容量是由系统变量 key_buffer_size 控制的。详情请看"7.5.2 Tuning Server Parameters"。

7.2.3 SELECT 查询的速度

通常情况下,想要让一个比较慢的 SELECT ... WHERE 查询变得更快的第一件事就是,先检查看看是否可以增加索引。所有对不同表的访问都通常使用索引。可以使用 EXPLAIN 语句来判断 SELECT 使用了哪些索引。详情请看"7.4.5 How MySQL Uses Indexes"和"7.2.1 EXPLAIN Syntax (Get Information About a SELECT)"。

以下是几个常用的提高 MyISAM 表查询速度的忠告:

想要让MySQL将查询优化的速度更快些,可以在数据表已经加载完全部数据后执行行 ANALYZE TABLE 或运行 myisamchk --analyze 命令。它更新了每个索引部分的值,这个值意味着相同记录的平均值(对于唯一索引来说,这个值则一直都是 1)。MySQL就会在当你使用基于一个非恒量表达式的两表连接时,根据这个值来决定使用哪个索引。想要查看结果,可以在分析完数据表后运行 SHOW INDEX FROM tbl_name 查看 Cardinality 字段的值。myisamchk --description --verbose 显示了索引的分布信息。

想要根据一个索引来排序数据,可以运行 myisamchk --sort-index --sort-records=1 (如果想要在索引 1 上做排序)。这对于有一个唯一索引并且想根据这个索引的顺序依次读取记录的话来说是一个提高查询速度的好办法。不过要注意的是,第一次在一个大表上做排序的话将会耗费很长时间。

7.2.4 MySQL如何优化 WHERE 子句

这个章节讲述了优化程序如何处理 WHERE 子句。例子中使用了 SELECT 语句,但是在 DELETE 和 UPDATE 语句中对 WHERE 子句的优化是一样的。

注意,关于MySQL优化的工作还在继续,因此本章节还没结束。MySQL做了很多优化工作,而不仅仅是文档中提到的这些。

MySQL的一些优化做法如下:

去除不必要的括号:

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

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

展开常量:

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


去除常量条件(在展开常量时需要):



(B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6)


-> B=5 OR B=6



常量表达示在索引中只计算一次


在单独一个表上做 COUNT(*) 而不使用 WHERE 时, 对于 MyISAM 和 HEAP 表就会直接从表信息中检索结果。在单独一个表上做任何表 NOT NULL 达式查询时也是这样做。

时间: 2024-09-23 21:11:49

MySQL手册版本 5.0.20-MySQL优化(三)的相关文章

MySQL手册版本 5.0.20-MySQL同步(一)

mysql 6 MySQL 同步 同步功能在MySQL 3.23.15就开始引进了,它可以把一个MySQL服务器上的数据复制到另一个服务器上去.本章描述了MySQL的各种复制特性.介绍了同步的概念,如何设置同步服务器,以及可用服务器的参照.还提供了一系列的常见问题及其答案,疑难解答. "14.6 Replication Statements"中介绍了同步相关的SQL语句语法. 我们建议经常访问"http://www.mysql.com"经常阅读本章的最新内容.同步功

MySQL手册版本 5.0.20-MySQL优化(二)

mysql|优化 7.2.1 EXPLAIN 语法(得到SELECT 的相关信息) EXPLAIN tbl_name 或者: EXPLAIN SELECT select_options EXPLAIN 语句可以被当作 DESCRIBE 的同义词来用,也可以用来获取一个MySQL要执行的 SELECT 语句的相关信息. EXPLAIN tbl_name 语法和 DESCRIBE tbl_name 或 SHOW COLUMNS FROM tbl_name 一样. 当在一个 SELECT 语句前使用关

MySQL手册版本 5.0.20-MySQL优化(一)

mysql|优化 7 MySQL 优化 数据库优化是一项很复杂的工作,因为这最终需要对系统优化的很好理解才行.尽管对系统或应用系统的了解不多的情况下优化效果还不错,但是如果想优化的效果更好,那么就需要对它了解更多才行. 本章主要讲解了几种优化MySQL的方法,并且给出了例子.记着,总有各种办法能让系统运行的更快,当然了,这需要更多的努力. 7.1 优化概述 让系统运行得快得最重要因素是数据库基本的设计.并且还必须清楚您的系统要用来做什么,以及存在的瓶颈. 最常见的系统瓶颈有以下几种: 磁盘搜索.

MySQL手册版本 5.0.20-MySQL优化(四) (1)(4)

可以在锁表后,一起执行几个语句来加速 INSERT 操作: LOCK TABLES a WRITE; INSERT INTO a VALUES (1,23),(2,34),(4,33); INSERT INTO a VALUES (8,26),(6,29); UNLOCK TABLES; 这对性能提高的好处在于:直到所有的 INSERT 语句都完成之后,索引缓存一次性刷新到磁盘中.通常情况是,多有少次 INSERT 语句就会有多数次索引缓存刷新到磁盘中的开销.如果能在一个语句中一次性插入多个值的

MySQL手册版本 5.0.20-MySQL优化(二) (1)

7.2.1 EXPLAIN 语法(得到SELECT 的相关信息) EXPLAIN tbl_name 或者: EXPLAIN SELECT select_options EXPLAIN 语句可以被当作 DESCRIBE 的同义词来用,也可以用来获取一个MySQL要执行的 SELECT 语句的相关信息. EXPLAIN tbl_name 语法和 DESCRIBE tbl_name 或 SHOW COLUMNS FROM tbl_name 一样. 当在一个 SELECT 语句前使用关键字 EXPLAI

MySQL手册版本 5.0.20-MySQL优化(四) (1)(2)

想要提高 ORDER BY 的速度,首先要看MySQL能否使用索引而非额外的排序过程.如果不能使用索引,可以试着遵循以下策略: 增加 sort_buffer_size 的值. 增加 read_rnd_buffer_size 的值. 修改 tmpdir,让它指向一个有很多剩余空间的专用文件系统.如果使用MySQL 4.1或更新,这个选项允许有多个路径用循环的格式.各个路径之间在 Unix 上用冒号(':')分隔开来,在 Windows,NetWare以及OS/2 上用分号(';').可以利用这个特

MySQL手册版本 5.0.20-MySQL优化(四) (1)

7.2.9 MySQL 如何优化 ORDER BY 在一些情况下,MySQL可以直接使用索引来满足一个 ORDER BY 或 GROUP BY 子句而无需做额外的排序. 尽管 ORDER BY 不是和索引的顺序准确匹配,索引还是可以被用到,只要不用的索引部分和所有的额外的 ORDER BY 字段在 WHERE 子句中都被包括了.下列的几个查询都会使用索引来解决 ORDER BY 或 GROUP BY 部分: SELECT * FROM t1 ORDER BY key_part1,key_part

MySQL手册版本 5.0.20-MySQL优化(四) (1)(5)

通常地,应该保存所有的冗余数据(在数据库原理中叫做"第三范式").然而,为了能取得更高的效率复制一些信息或者创建摘要表也是划算的. 存储过程或者 UDFs(用户定义函数) 的方式在执行一些任务时可能性能更高.尽管如此,当数据库不支持这些特性时,还是有其他的替代方法可以达到目的,即使它们有点慢. 可以从查询缓存或应答中取得结果,然后将很多次的插入及更新操作放在一起做.如果数据库支持表锁(如MySQL和ORACLE),那么这就可以确保索引缓存在所有的更新操作之后只需要刷新一次. 当不需要直

MySQL手册版本 5.0.20-MySQL优化(四) (1)(3)

7.2.12 加速 INSERT 插入一条记录花费的时间由以下几个因素决定,后面的数字大致表示影响的比例: 连接:(3) 发送查询给服务器:(2) 解析查询:(2) 插入记录:(1 x 记录大小) 插入索引:(1 x 索引数量) 关闭:(1) 这里并没有考虑初始化时打开数据表的开销,因为每次运行查询只会做这么一次. 如果是 B-tree 索引的话,随着索引数量的增加,插入记录的速度以 log N 的比例下降. 可以使用以下几种方法来提高插入速度: 如果要在同一个客户端在同一时间内插入很多记录,可