网站首页 > 技术文章 正文
概述
由于业务的需要:查看某列值为NULL的记录有多少。这是一个十分简单的需求,同时也很容易实现。无非就是使用如下语句:
SELECT * FROM table WHERE xx IS NULL;
结果得出的结果只有几十条记录,但是执行的时间比我想象中的长了许多。一般这样的查询只是要秒秒钟的问题,但是却花了十几秒,而平时使用IS NOT NULL也没有那么慢啊。所以后面抽空就做了个实验来简单测试下。
基础数据准备
DROP TABLE t PURGE; CREATE TABLE t(a NUMBER); CREATE INDEX idx_t ON t(a); INSERT INTO t VALUES(NULL); INSERT INTO t VALUES(NULL); INSERT INTO t VALUES(1); INSERT INTO t VALUES(1); INSERT INTO t VALUES(1); INSERT INTO t VALUES(1); INSERT INTO t VALUES(1); INSERT INTO t VALUES(1); INSERT INTO t VALUES(1); COMMIT; --收集表统计信息 EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname=>'SCOTT', tabname=>'T'); EXEC DBMS_STATS.GATHER_INDEX_STATS(ownname=>'SCOTT', indname=>'IDX_T');
对比执行计划
SET NULL UNKOWN --设置如果只为NULL就以UNKOWN显示 SET AUTOTRACE ON EXPLAIN SELECT * FROM t WHERE a IS NULL; SELECT * FROM t WHERE a IS NOT NULL;
可以看出使用IS NULL时候没有使用索引,而使用IS NOT NULL有使用索引。
查看IDX_T索引的所在的列
SELECT TABLE_NAME, INDEX_NAME, COLUMN_NAME FROM USER_IND_COLUMNS WHERE INDEX_NAME = 'IDX_T';
很明显的展示了在表T的a列上是有索引的
查看索引统计信息
SELECT index_name, num_rows from user_indexes where index_name = 'IDX_T';
从上面可以看出索引的统计信息的NUM_ROWS字段只有7行,而实际的数据总量是9行。按道理应该索引的NUM_ROWS应该是9才对缺少了2,很明显少了值为NULL的那2行。原来索引是不将NULL值的行记录在索引中的。
创建一个伪列的索引
SET AUTOTRACE OFF DROP INDEX idx_t; CREATE INDEX idx_t ON t(a, 0); EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname=>'SCOTT', tabname=>'T'); EXEC DBMS_STATS.GATHER_INDEX_STATS(ownname=>'SCOTT', indname=>'IDX_T'); SET AUTOTRACE ON EXPLAIN SELECT * FROM t WHERE a IS NULL; SELECT * FROM t WHERE a IS NOT NULL;
从上面可以看到IS NULL 走索引了,IS NOT NULL 也走索引。
查看索引统计信息
SELECT index_name, num_rows from user_indexes where index_name = 'IDX_T';
索引的统计信息是9和表的行数是一样的。
篇幅有限,就写到这里了,这里大家可以抽空自己用函数索引来测试下,看到的num_rows也会不一样的,后面会分享更多devops和DBA方面的内容,感兴趣的朋友可以关注一下~
猜你喜欢
- 2024-11-10 详解Oracle数据库is null和is not null在索引上的区别
- 2024-11-10 Oracle中会产生索引抑制的几种情况
- 2024-11-10 Oracle 分区表之相关陷阱 oracle分区表的缺点
- 2024-11-10 玩dotNetCore及EF6失败还是聊下Oracle索引吧
- 2024-11-10 如何“破解”Oracle数据库性能测试过程中索引使用问题?
- 2024-11-10 SQL查询慢,是因为没用对索引 sql语句查询慢 从哪些方面分析
- 2024-11-10 在Oracle中,索引有什么优点和缺点?
- 2024-11-10 Oracle 数据库索引扫描方式 oracle数据库索引查询
- 2024-11-10 Oracle 分区索引类型简述 oracle分区表索引是否失效
- 2024-11-10 Oracle 索引是一种单独的物理结构
你 发表评论:
欢迎- 616℃几个Oracle空值处理函数 oracle处理null值的函数
- 609℃Oracle分析函数之Lag和Lead()使用
- 597℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 593℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 590℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 581℃【数据统计分析】详解Oracle分组函数之CUBE
- 570℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 560℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
-
- PageHelper - 最方便的 MyBatis 分页插件
- 面试二:pagehelper是怎么实现分页的,
- MyBatis如何实现分页查询?(mybatis-plus分页查询)
- SpringBoot 各种分页查询方式详解(全网最全)
- 如何在Linux上运行exe文件,怎么用linux运行windows软件
- 快速了解hive(快速了解美国50个州)
- Python 中的 pyodbc 库(pydbclib)
- Linux搭建Weblogic集群(linux weblogic部署项目步骤)
- 「DM专栏」DMDSC共享集群之部署(一)——共享存储配置
- 故障分析 | MySQL 派生表优化(mysql pipe)
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- 前端获取当前时间 (50)
- Oracle RAC (76)
- oracle恢复 (77)
- oracle 删除表 (52)
- oracle 用户名 (80)
- oracle 工具 (55)
- oracle 内存 (55)
- oracle 导出表 (62)
- oracle约束 (54)
- oracle 中文 (51)
- oracle链接 (54)
- oracle的函数 (58)
- 前端调试 (52)
本文暂时没有评论,来添加一个吧(●'◡'●)