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#汉字区位码查询
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的每个值匹配的数据行只有一个。
更多精彩
赞助商链接