喜悦国际村 
» 游客:  注册 | 登录 | 搜索 | 统计 | 喜悦证交所 | 帮助

RSS 订阅当前论坛  

$5.95 Web Hosting     

上一主题 下一主题
     
标题: 使用SELECT查询时,where条件中使用大于跟使用大于等于差很多,这是为什么?  
 
chaizx (chaizx)
高级会员
Rank: 4
初级会员



UID 24298
精华 1
积分 535
帖子 244
金钱 525 喜悦币
威望 10
人脉 0
阅读权限 50
注册 2003-11-1
状态 离线
[广告]: 代充Paypal帐号美元
使用SELECT查询时,where条件中使用大于跟使用大于等于差很多,这是为什么?

上次参加php技术交流讨论时,有人提出这样一个问题:
在数据量非常大的表中,大致有100万以上的数据量时:
    使用SELECT * FROM `tbl` WHERE `field`>100;
与使用SELECT * FROM `tbl` WHERE `field`>=100;
前者与后者的效率和速度差很多,也就是说在使用大于的效率跟使用大于等于的效率差很多,
这是为什么?
请高手指点?
2007-9-30 09:30 AM#1
查看资料  Blog  发短消息  QQ  顶部
 
歪歪飞扬
注册会员
Rank: 2


UID 95184
精华 0
积分 94
帖子 77
金钱 94 喜悦币
威望 0
人脉 0
阅读权限 20
注册 2007-7-11
状态 离线
[广告]: 代充Paypal帐号美元
单元素索引的范围访问方法
对于单元素索引,可以用WHERE子句中的相应条件很方便地表示索引值区间,因此我们称为范围条件而不是“区间”。

单元素索引范围条件的定义如下:

·         对于BTREE和HASH索引,当使用=、<=>、IN、IS NULL或者IS NOT NULL操作符时,关键元素与常量值的比较关系对应一个范围条件。

·         对于BTREE索引,当使用>、<、>=、<=、BETWEEN、!=或者<>,或者LIKE 'pattern'(其中 'pattern'不以通配符开始)操作符时,关键元素与常量值的比较关系对应一个范围条件。

·         对于所有类型的索引,多个范围条件结合OR或AND则产生一个范围条件。

前面描述的“常量值”系指:

·         查询字符串中的常量

·         同一联接中的const或system表中的列

·         无关联子查询的结果

·         完全从前面类型的子表达式组成的表达式

下面是一些WHERE子句中有范围条件的查询的例子:

SELECT * FROM t1
    WHERE key_col > 1
    AND key_col < 10;

SELECT * FROM t1
    WHERE key_col = 1
    OR key_col IN (15,18,20);

SELECT * FROM t1
    WHERE key_col LIKE 'ab%'
    OR key_col BETWEEN 'bar' AND 'foo';

请注意在常量传播阶段部分非常量值可以转换为常数。

MySQL尝试为每个可能的索引从WHERE子句提取范围条件。在提取过程中,不能用于构成范围条件的条件被放弃,产生重叠范围的条件组合到一起,并且产生空范围的条件被删除。

例如,考虑下面的语句,其中key1是有索引的列,nonkey没有索引:

SELECT * FROM t1 WHERE
   (key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR
   (key1 < 'bar' AND nonkey = 4) OR
   (key1 < 'uux' AND key1 > 'z');
key1的提取过程如下:

1.    用原始WHERE子句开始:

2.    (key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR

3.     (key1 < 'bar' AND nonkey = 4) OR

4.     (key1 < 'uux' AND key1 > 'z')

5.    删除nonkey = 4和key1 LIKE '%b',因为它们不能用于范围扫描。删除它们的正确途径是用TRUE替换它们,以便进行范围扫描时不会丢失匹配的记录。用TRUE替换它们后,可以得到:

6.            (key1 < 'abc' AND (key1 LIKE 'abcde%' OR TRUE)) OR
7.            (key1 < 'bar' AND TRUE) OR
8.            (key1 < 'uux' AND key1 > 'z')
9.    取消总是为true或false的条件:

·         (key1 LIKE 'abcde%' OR TRUE)总是true

·         (key1 < 'uux' AND key1 > 'z')总是false

用常量替换这些条件,我们得到:

(key1 < 'abc' AND TRUE) OR (key1 < 'bar' AND TRUE) OR (FALSE)
删除不必要的TRUE和FALSE常量,我们得到

(key1 < 'abc') OR (key1 < 'bar')
10.将重叠区间组合成一个产生用于范围扫描的最终条件:

11.        (key1 < 'bar')
总的来说(如前面的例子所述),用于范围扫描的条件比WHERE子句限制少。MySQL再执行检查以过滤掉满足范围条件但不完全满足WHERE子句的行。

范围条件提取算法可以处理嵌套的任意深度的AND/OR结构,并且其输出不依赖条件在WHERE子句中出现的顺序。
2007-10-1 09:03 PM#2
查看资料  Blog  发短消息  QQ  顶部
 
chaizx (chaizx)
高级会员
Rank: 4
初级会员



UID 24298
精华 1
积分 535
帖子 244
金钱 525 喜悦币
威望 10
人脉 0
阅读权限 50
注册 2003-11-1
状态 离线
[推荐阅读] 有没有到大连的火车票转让?
谢谢楼主的热心!
2007-10-7 08:59 AM#3
查看资料  Blog  发短消息  QQ  顶部
 
zhaofei299
新手上路
Rank: 1


UID 84524
精华 0
积分 36
帖子 30
金钱 36 喜悦币
威望 0
人脉 0
阅读权限 10
注册 2006-12-9
状态 离线
[推荐阅读] 代码上的版本信息是如何生成的???
加了个并且吧!
2007-10-9 07:43 PM#4
查看资料  访问主页  发短消息  顶部
     


  可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题 | 开通个人空间  


 




Powered by Discuz! 6.1.0  © 2001-2010 Comsenz Inc.
Processed in 0.023686 second(s), 6 queries

(冀ICP备05009913号) 管理员:sadly 邮箱/MSN: sadly@phpx.com QQ:824008(长隐) 清除 Cookies - - Archiver - WAP