WEB开发网
开发学院数据库MySQL MySQL查询优化系列讲座之查询优化器 阅读

MySQL查询优化系列讲座之查询优化器

 2007-11-11 13:40:45 来源:WEB开发网   
核心提示: ·一个身份证升位号码查询系统的源码·将查询结果导出到Excel的另一个方法·C#通过查询结果进行分页·五种查询Internet连接状态[含IP]的方·Access的跨库查询·Hibernate对多表关联查询·SQL应用-
    ·一个身份证升位号码查询系统的源码
    ·将查询结果导出到Excel的另一个方法
    ·C#通过查询结果进行分页
    ·五种查询Internet连接状态[含IP]的方
    ·Access的跨库查询
    ·Hibernate对多表关联查询
    ·SQL应用--查询最大版本值
    ·SQL数据查询的例子,包括许多复杂的查
    ·Hibernate分页查询原理解读
    ·c#汉字区位码查询
  为了使这个查询的效率更高,给其中一个联结列添加索引并重新执行EXPLAIN语句:

MySQL(和PHP搭配之最佳组合)> ALTER TABLE t2 ADD INDEX (i2);
MySQL(和PHP搭配之最佳组合)> EXPLAIN SELECT t1.i1, t2.i2 FROM t1, t2 WHERE t1.i1 = t2.i2\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 1000
Extra:
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: t2
type: ref
possible_keys: i2
key: i2
key_len: 5
ref: sampdb.t1.i1
rows: 10
Extra: Using where; Using index

  我们可以看到性能提高了。T1的输出没有改变(表明还是需要进行全表扫描),但是优化器处理t2的方式就有所不同了:

  · 类型从ALL改变为ref,意味着可以使用参考值(来自t1的值)来执行索引查找,定位t2中合格的数据行。

  · 参考值在参考(ref)字段中给出了:sampdb.t1.i1。

  · 行数值从1000降低到了10,显示出优化器相信对于t1中的每一行,它只需要检查t2中的10行(这是一个悲观的估计值。实际上,在t2中只有一行与t1中数据行匹配。我们在后面会看到如何帮助优化器改善这个估计值)。数据行组合的全部估计值使1000×10=10000。它比前面的没有索引的时候估计出来的一百万好多了。

  对t1进行索引有价值吗?实际上,对于这个特定的联结操作,扫描一张表是必要的,因此没有必要对t1建立索引。如果你想看到效果,可以索引t1.i1并再次运行EXPLAIN:

MySQL(和PHP搭配之最佳组合)> ALTER TABLE t1 ADD INDEX (i1);
MySQL(和PHP搭配之最佳组合)> EXPLAIN SELECT t1.i1, t2.i2 FROM t1, t2 WHERE t1.i1 = t2.i2\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
type: index
possible_keys: i1
key: i1
key_len: 5
ref: NULL
rows: 1000
Extra: Using index
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: t2
type: ref
possible_keys: i2
key: i2
key_len: 5
ref: sampdb.t1.i1
rows: 10
Extra: Using where; Using index

  上面的输出与前面的EXPLAIN的输出相似,但是添加索引对t1的输出有一些改变。类型从NULL改成了index,附加(Extra)从空的改成了Using index。这些改变表明,尽管对索引的值仍然需要执行全表扫描,但是优化器还是可以直接从索引文件中读取值,根据不需要使用数据文件。你可以从MyISAM表中看到这类结果,在这种情况下,优化器知道自己只询问索引文件就能够得到所有需要的信息。对于InnoDB 和BDB表也有这样的结果,在这种情况下优化器可以单独使用索引中的信息而不用搜索数据行。

  我们可以运行ANALYZE TABLE使优化器进一步优化估计值。这会引起服务器生成键值的静态分布。分析上面的表并再次运行EXPLAIN得到了更好的估计值:

MySQL(和PHP搭配之最佳组合)> ANALYZE TABLE t1, t2;
MySQL(和PHP搭配之最佳组合)> EXPLAIN SELECT t1.i1, t2.i2 FROM t1, t2 WHERE t1.i1 = t2.i2\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
type: index
possible_keys: i1
key: i1
key_len: 5
ref: NULL
rows: 1000
Extra: Using index
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: t2
type: ref
possible_keys: i2
key: i2
key_len: 5
ref: sampdb.t1.i1
rows: 1
Extra: Using where; Using index

  在这种情况下,优化器估计在t2中与t1的每个值匹配的数据行只有一个。

上一页  1 2 3 4 5  下一页

Tags:MySQL 查询 优化

编辑录入:coldstar [复制链接] [打 印]
赞助商链接