查看: 7587|回复: 24

受楼下老大的NULL贴启发,讲两个NULL与索引的小技巧

[复制链接]
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
跳转到指定楼层
1#
发表于 2008-7-12 03:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1.既然NULL是可以进复合索引的,在我们需要对NULL进行索引时,就可以构造一个“伪复合索引”:

CREATE INDEX my_index ON my_table(my_column,0);

后面这个零就是加入的伪列。这样以后在有 my_column IS NULL 的条件就可以利用索引了(当然最终使用与否还得由CBO决定)。

2.不想索引的行,即使不是NULL, 也可用函数把它剔除。
  假设有status_id列,里面有0:未处理,1:已处理 两种状态,我们关心的仅仅是0的行,处理完就会改成1. 这样表中0的行仅仅是少数,大部分是1的行,数据量多了BTREE索引的维护就有开销。
  这时可以建立这样的索引:
  CREATE INDEX my_index ON my_table(DECODE(status_id,0,0));
  它只对0行数据进行索引。当你要取未处理数据时,SELECT * FROM my_table WHERE DECODE(status_id,0,0)=0 就可以高效利用索引。
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
2#
 楼主| 发表于 2008-7-12 03:53 | 只看该作者
另有一个陷阱要小心避免:
SELECT ... FROM t1 WHERE my_column NOT IN (SELECT my_column FROM t2);

假如这个子查询SELECT my_column FROM t2里面有NULL, 那么主查询就一行数据也出不来了! 必须改用:
SELECT ... FROM t1 WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE t2.my_column = t1.my_column);

使用道具 举报

回复
论坛徽章:
33
劳斯莱斯
日期:2013-08-08 14:01:23三菱
日期:2013-09-28 10:16:06一汽
日期:2013-11-19 17:01:11凯迪拉克
日期:2013-12-07 17:11:282014年新春福章
日期:2014-02-18 16:42:02马上有房
日期:2014-02-18 16:42:02itpub13周年纪念徽章
日期:2014-09-27 14:20:21itpub13周年纪念徽章
日期:2014-10-08 15:13:38懒羊羊
日期:2015-03-04 14:52:112015年新春福章
日期:2015-03-06 11:58:18
3#
发表于 2008-7-12 08:07 | 只看该作者
原帖由 newkid 于 2008-7-12 03:53 发表
另有一个陷阱要小心避免:
SELECT ... FROM t1 WHERE my_column NOT IN (SELECT my_column FROM t2);

假如这个子查询SELECT my_column FROM t2里面有NULL, 那么主查询就一行数据也出不来了! 必须改用:
SELECT ... FROM t1 WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE t2.my_column = t1.my_column);

支持,这个真还要小心!!

使用道具 举报

回复
论坛徽章:
2
ITPUB8周年纪念徽章
日期:2009-09-27 10:21:22优秀写手
日期:2014-02-08 06:00:12
4#
发表于 2008-7-12 08:27 | 只看该作者
原帖由 newkid 于 2008-7-12 03:53 发表
另有一个陷阱要小心避免:
SELECT ... FROM t1 WHERE my_column NOT IN (SELECT my_column FROM t2);

假如这个子查询SELECT my_column FROM t2里面有NULL, 那么主查询就一行数据也出不来了! 必须改用:
SELECT ... FROM t1 WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE t2.my_column = t1.my_column);

问一个,为什么查不出了?
另外,楼主说的第二种情况,用位图索引是否更好些?

使用道具 举报

回复
论坛徽章:
9607
土豪章
日期:2013-12-31 14:11:39土豪章
日期:2013-12-31 14:11:39阿森纳
日期:2013-06-03 17:00:31阿森纳
日期:2013-10-11 09:27:58法拉利
日期:2013-12-27 15:20:30林肯
日期:2013-12-27 15:19:09法拉利
日期:2013-12-27 15:20:30法拉利
日期:2013-12-27 15:20:30法拉利
日期:2013-12-27 15:20:30法拉利
日期:2013-12-27 15:20:30
5#
发表于 2008-7-12 08:38 | 只看该作者
恩,是的,在not in 和in,not exists 和exists 的区别那个帖子强调了

使用道具 举报

回复
论坛徽章:
2
ITPUB8周年纪念徽章
日期:2009-09-27 10:21:22优秀写手
日期:2014-02-08 06:00:12
6#
发表于 2008-7-12 08:50 | 只看该作者

小马哥,那贴在那儿,我学习一下

使用道具 举报

回复
论坛徽章:
33
劳斯莱斯
日期:2013-08-08 14:01:23三菱
日期:2013-09-28 10:16:06一汽
日期:2013-11-19 17:01:11凯迪拉克
日期:2013-12-07 17:11:282014年新春福章
日期:2014-02-18 16:42:02马上有房
日期:2014-02-18 16:42:02itpub13周年纪念徽章
日期:2014-09-27 14:20:21itpub13周年纪念徽章
日期:2014-10-08 15:13:38懒羊羊
日期:2015-03-04 14:52:112015年新春福章
日期:2015-03-06 11:58:18
7#
发表于 2008-7-12 08:51 | 只看该作者
原帖由 jvkojvko 于 2008-7-12 08:38 发表
恩,是的,在not in 和in,not exists 和exists 的区别那个帖子强调了

Show me the link,PLS!

使用道具 举报

回复
论坛徽章:
9607
土豪章
日期:2013-12-31 14:11:39土豪章
日期:2013-12-31 14:11:39阿森纳
日期:2013-06-03 17:00:31阿森纳
日期:2013-10-11 09:27:58法拉利
日期:2013-12-27 15:20:30林肯
日期:2013-12-27 15:19:09法拉利
日期:2013-12-27 15:20:30法拉利
日期:2013-12-27 15:20:30法拉利
日期:2013-12-27 15:20:30法拉利
日期:2013-12-27 15:20:30
8#
发表于 2008-7-12 09:21 | 只看该作者
http://www.itpub.net/viewthread. ... hlight=not%2Bexists

晕,财哥,你坐着sf呢,哈

使用道具 举报

回复
论坛徽章:
2
ITPUB8周年纪念徽章
日期:2009-09-27 10:21:22优秀写手
日期:2014-02-08 06:00:12
9#
发表于 2008-7-12 09:24 | 只看该作者

财哥学习不认真,打pp

使用道具 举报

回复
论坛徽章:
33
劳斯莱斯
日期:2013-08-08 14:01:23三菱
日期:2013-09-28 10:16:06一汽
日期:2013-11-19 17:01:11凯迪拉克
日期:2013-12-07 17:11:282014年新春福章
日期:2014-02-18 16:42:02马上有房
日期:2014-02-18 16:42:02itpub13周年纪念徽章
日期:2014-09-27 14:20:21itpub13周年纪念徽章
日期:2014-10-08 15:13:38懒羊羊
日期:2015-03-04 14:52:112015年新春福章
日期:2015-03-06 11:58:18
10#
发表于 2008-7-12 11:06 | 只看该作者
原帖由 jvkojvko 于 2008-7-12 09:21 发表
http://www.itpub.net/viewthread. ... hlight=not%2Bexists

晕,财哥,你坐着sf呢,哈

谢谢,看看是什么,估计是看过的

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表