XiaoHui.net 笑汇程序员论坛首页
工作并快乐着,职业并休闲着
寻梦的岁月从不言辛苦几许,
不问收获几多……
» 游客:  申请新用户 | 登录 | 会员 | 统计 | 帮助 » XiaoHui.Net 笑汇程序员论坛 | 纯文字版 | 全站索引 | XiaoHui.com


[MySQL/Postgresql] [优化] 4 MySQL索引的使用

RSS 订阅当前论坛  

上一主题 下一主题
     

标题: [MySQL/Postgresql] [优化] 4 MySQL索引的使用  
  本主题被作者加入到他/她的 Blog 中  
 
FlyFire
传说中的水手
Rank: 5Rank: 5


UID 4
精华 1
积分 330
帖子 320
阅读权限 1
注册 2001-1-25
来自 暴力球场
状态 离线
[优化] 4 MySQL索引的使用

索引被用来快速找出在一个列上用一特定值的行。没有索引,MySQL不得不首先以第一条记录开始并然后读完整个表直到它找出相关的行。表越大,花费时间越多。如果表对于查询的列有一个索引,MySQL能快速到达一个位置去搜寻到数据文件的中间,没有必要考虑所有数据。如果一个表有1000行,这比顺序读取至少快100倍。注意你需要存取几乎所有1000行,它较快的顺序读取,因为此时我们避免磁盘寻道。

所有的MySQL索引(PRIMARY、UNIQUE和INDEX)在B树中存储。字符串是自动地压缩前缀和结尾空间。见7.27 CREATE INDEX句法。

索引用于:

快速找出匹配一个WHERE子句的行。
当执行联结时,从其他表检索行。
对特定的索引列找出MAX()或MIN()值。
如果排序或分组在一个可用键的最左面前缀上进行(例如,ORDER BY key_part_1,key_part_2),排序或分组一个表。如果所有键值部分跟随DESC,键以倒序被读取。
在一些情况中,一个查询能被优化来检索值,不用咨询数据文件。如果对某些表的所有使用的列是数字型的并且构成某些键的最左面前缀,为了更快,值可以从索引树被检索出来。
假定你发出下列SELECT语句:

mysql> SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;

如果一个多列索引存在于col1和col2上,适当的行可以直接被取出。如果分开的单行列索引存在于col1和col2上,优化器试图通过决定哪个索引将找到更少的行并来找出更具限制性的索引并且使用该索引取行。

如果表有一个多列索引,任何最左面的索引前缀能被优化器使用以找出行。例如,如果你有一个3行列索引(col1,col2,col3),你已经索引了在(col1)、(col1,col2)和(col1,col2,col3)上的搜索能力。

如果列不构成索引的最左面前缀,MySQL不能使用一个部分的索引。假定你下面显示的SELECT语句:

mysql> SELECT * FROM tbl_name WHERE col1=val1;
mysql> SELECT * FROM tbl_name WHERE col2=val2;
mysql> SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3;

如果一个索引存在于(col1、col2、col3)上,只有上面显示的第一个查询使用索引。第二个和第三个查询确实包含索引的列,但是(col2)和(col2、col3)不是(col1、col2、col3)的最左面前缀。

如果LIKE参数是一个不以一个通配符字符起始的一个常数字符串,MySQL也为LIKE比较使用索引。例如,下列SELECT语句使用索引:

mysql> select * from tbl_name where key_col LIKE "Patrick%";
mysql> select * from tbl_name where key_col LIKE "Pat%_ck%";

在第一条语句中,只考虑有"Patrick" <= key_col < "Patricl"的行。在第二条语句中,只考虑有"Pat" <= key_col < "Pau"的行。

下列SELECT语句将不使用索引:

mysql> select * from tbl_name where key_col LIKE "%Patrick%";
mysql> select * from tbl_name where key_col LIKE other_col;

在第一条语句中,LIKE值以一个通配符字符开始。在第二条语句中,LIKE值不是一个常数。

如果 column_name 是一个索引,使用column_name IS NULL的搜索将使用索引。

MySQL通常使用找出最少数量的行的索引。一个索引被用于你与下列操作符作比较的列:=、>、>=、<、<=、BETWEEN和一个有一个非通配符前缀象'something%'的LIKE的列。

任何不跨越的在WHERE子句的所有AND层次的索引不用来优化询问。

下列WHERE子句使用索引:

... WHERE index_part1=1 AND index_part2=2
... WHERE index=1 OR A=10 AND index=2      /* index = 1 OR index = 2 */
... WHERE index_part1='hello' AND index_part_3=5
          /* optimized like "index_part1='hello'" */
这些WHERE子句不使用索引:

... WHERE index_part2=1 AND index_part3=2  /* index_part_1 is not used */
... WHERE index=1 OR A=10                  /* No index */
... WHERE index_part1=1 OR index_part2=10  /* No index spans all rows */
[ 本帖最后由 FlyFire 于 2006-4-19 12:31 编辑 ]


Don't say good bye....
2006-4-17 22:14#1
查看资料  Blog  发短消息  顶部
 
FlyFire
传说中的水手
Rank: 5Rank: 5


UID 4
精华 1
积分 330
帖子 320
阅读权限 1
注册 2001-1-25
来自 暴力球场
状态 离线
累了, 不知道是否有人喜欢. 明天继续贴.

Don't say good bye....
2006-4-17 22:15#2
查看资料  Blog  发短消息  顶部
 
漫天红枫
版主
Rank: 7Rank: 7Rank: 7


UID 11026
精华 0
积分 118
帖子 118
阅读权限 100
注册 2003-3-9
来自 湖南长沙
状态 离线
非常好,很实用呀.好贴.同时感谢 FlyFire 对这个版块的支持.

[ 本帖最后由 漫天红枫 于 2006-4-18 12:45 编辑 ]
2006-4-18 09:13#3
查看资料  Blog  发短消息  QQ  顶部
 
eyelet
管理员
Rank: 9Rank: 9Rank: 9
我的漂亮美眉


UID 5
精华 2
积分 1852
帖子 1832
阅读权限 200
注册 2002-2-7
状态 离线
很不错

NB Vista技术网——www.nbvista.com
2006-4-18 17:03#4
查看资料  访问主页  Blog  发短消息  顶部
 
princer007
小水手
Rank: 1



UID 21288
精华 0
积分 4
帖子 4
阅读权限 10
注册 2006-4-17
状态 离线
喜欢,楼主继续~!
2006-8-8 09:20#5
查看资料  Blog  发短消息  顶部
     


  可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题  


 


所有时间为 GMT+8, 现在时间是 2008-11-20 20:26 Powered by Discuz! 4.1.0 清除 Cookies - XiaoHui.Net 笑汇程序员论坛 - Archiver