iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >ORACLE 索引和MYSQL INNODB 辅助索引对NULL的处理区别有哪些
  • 349
分享到

ORACLE 索引和MYSQL INNODB 辅助索引对NULL的处理区别有哪些

2024-04-02 19:04:59 349人浏览 安东尼
摘要

这篇文章将为大家详细讲解有关oracle 索引和Mysql INNODB 辅助索引对NULL的处理区别有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

这篇文章将为大家详细讲解有关oracle 索引Mysql INNODB 辅助索引对NULL的处理区别有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

ORACLE 索引和mysql INNODB 辅助索引对NULL的处理

我们清楚ORACLE中的b+索引是对键值的NULL进行存储的,以致于我们 IS NULL这种肯定是用不到索引的,
当然这提及的ORACLE表为堆表,索引为单列B+树索引,(有一种优化方式为建立组合索引如create index xx on tab(a,'1')
这样来保证索引记录NULL值
这样DUMP出来为
.....
row#11[7886] flag: ------, lock: 2, len=12
col 0; NULL
col 1; len 1; (1):  31
col 2; len 6; (6):  01 00 00 d5 00 0a
....
记录了NULL值)


而且在某些情况下,比如
select count(b) from tab ;
这种如果b列没有显示的申明为not null属性也是用不到的,必须加上not null或者在where条件中加上
b is not null。
很明显这些问题都是ORACLE索引并不存储对null值进行存储


而mysql innodb 不同如果 is null可定用到b+索引的,那么说明INNODB 是保存的NULL值的。
本文将通过对ORACLE INDEX进行BLOCK DUMP和对innodb 辅助索引进行内部访问来证明,
为了简单起见我还是建立两个列的表如下:
ORACLE:
 create table test (a int,b int,primary key(a));
 create index b_index on test(b);
mysql innodb:
 create table test (a int,b int,primary key(a),key(b));
 
插入一些值:
insert into test values(1,1);
insert into test values(5,NULL);
insert into test values(3,1);
insert into test values(4,2);
insert into test values(10,NULL);
insert into test values(7,4);
insert into test values(8,5);
insert into test values(11,NULL);
insert into test values(20,6);
insert into test values(21,6);
insert into test values(19,NULL);
insert into test values(16,7);


我们通过查看执行计划:
ORACLE:
SQL> select * from test where b is null;


         A          B
---------- ----------
         5
        10
        11
        19


Execution Plan
----------------------------------------------------------
Plan hash value: 1357081020


--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     4 |   104 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| TEST |     4 |   104 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------


mysql:
mysql> explain select * from test where b is null;
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref   | rows | filtered | Extra                    |
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+--------------------------+
|  1 | SIMPLE      | test  | NULL       | ref  | b             | b    | 5       | const |    4 |   100.00 | Using where; Using index |
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)


为了起到强制作用ORACLE使用HINT来指定索引,但是由于根本用不到所以ORACLE已经忽略,MYSQL innodb已经用到。


接下来我们来分析其内部结构:
ORACLE:
SQL>  SELECT OBJECT_ID FROM DBA_OBJECTS where object_name='B_INDEX';


 OBJECT_ID
----------
     75905


SQL> oradebug setmypid
Statement processed.
SQL> oradebug tracefile_name
/home/oracle/diag/rdbms/mytest/mytest/trace/mytest_ora_2996.trc
SQL>  alter session set events 'immediate trace name treedump level 75905';


Session altered.
查看trace文件
核心内容:
*** 2016-11-16 22:45:55.053
----- begin tree dump
leaf: 0x10000c3 16777411 (0: nrow: 8 rrow: 8)
----- end tree dump
因为B+树只有一个节点就是DBA 16777411,我们单独DUMP这个块
进行DBA换算


SQL>  select dbms_utility.data_block_address_file(16777411),
  2            dbms_utility.data_block_address_block(16777411) from dual;


DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(16777411)
----------------------------------------------
DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(16777411)
-----------------------------------------------
                                             4
                                            195
进行BLOCK DUMP:
SQL> oradebug setmypid
Statement processed.
SQL> oradebug tracefile_name
/home/oracle/diag/rdbms/mytest/mytest/trace/mytest_ora_3009.trc
SQL> alter system dump datafile 4 block 195;


查看TRACE 文件:
块数据:
row#0[8020] flag: ------, lock: 2, len=12
col 0; len 2; (2):  c1 02
col 1; len 6; (6):  01 00 00 b7 00 00
row#1[8008] flag: ------, lock: 2, len=12
col 0; len 2; (2):  c1 02
col 1; len 6; (6):  01 00 00 b7 00 02
row#2[7996] flag: ------, lock: 2, len=12
col 0; len 2; (2):  c1 03
col 1; len 6; (6):  01 00 00 b7 00 03
row#3[7984] flag: ------, lock: 2, len=12
col 0; len 2; (2):  c1 05
col 1; len 6; (6):  01 00 00 b7 00 05
row#4[7972] flag: ------, lock: 2, len=12
col 0; len 2; (2):  c1 06
col 1; len 6; (6):  01 00 00 b7 00 06
row#5[7960] flag: ------, lock: 2, len=12
col 0; len 2; (2):  c1 07
col 1; len 6; (6):  01 00 00 b7 00 08
row#6[7948] flag: ------, lock: 2, len=12
col 0; len 2; (2):  c1 07
col 1; len 6; (6):  01 00 00 b7 00 09
row#7[7936] flag: ------, lock: 2, len=12
col 0; len 2; (2):  c1 08
col 1; len 6; (6):  01 00 00 b7 00 0b


有8记录,其顺序按照b列大小排序及COL 0,COL2是ROWID
注意COL是number类型有ORACLE自己算法
算法参考:
Http://blog.itpub.net/7728585/viewspace-2128563/
其实这里压根就没有存储4行NULL行因为我们一共12行,dump出来只有8行


下面看看MYSQL INNODB:
因为选择了2列的表我的程序可以直接跑出索引结果:
详细参考:
http://blog.itpub.net/7728585/viewspace-2126344/
这里跑一下


./mysqlblock test.ibd -d
current read blocks is : 0 --This Block is file space header blocks!
current read blocks is : 1 --This Block is insert buffer bitmap  blocks!
current read blocks is : 2 --This Block is inode blocks!
current read blocks is : 3 --This Block is data blocks( index pages)!
current read blocks is : 4 --This Block is data blocks( index pages)! --这里是我们需要查看的辅助索引的块


[root@testmy test]# ./a.out test.ibd 4
Index_no is:117
find first one record!
B:5,A:-2147483616-->      
B:10,A:-2147483592-->
B:11,A:-2147483568-->
B:19,A:-2147483544-->
B:1,A:1-->
B:1,A:3-->
B:2,A:4-->
B:4,A:7-->
B:5,A:8-->
B:6,A:20-->
B:6,A:21-->
B:7,A:16-->


B:5,A:-2147483616--> insert into test values(5,NULL);
B:10,A:-2147483592--> insert into test values(10,NULL);
B:11,A:-2147483568--> insert into test values(11,NULL);
B:19,A:-2147483544--> insert into test values(19,NULL);
我们可以看到INNODB确实记录了NULL值,但是这是如何记录的?
我们上面跑的结果看到是一个很大的负数,但是这个程序并没有考虑NULL值,也就是
全部是not null的情况下正确,

其实不要忘记了行头的 NULL辨识位图:
nullable field bitmap   (1 bit * null field)
每个NULL值占用一个一位(bit),如果不满一个字节按一个字节算,如果不存在NULL值
至少占用一个字节为00。
接下来我们还是要看看这个位,老办法而进行打开(无语累)
看了2进制后如下:
010000180026 实际这6个字节的第一个字节就是NULL 位图及01
80000005
实际上MYSQL INNODB也没有真正的存储字段的NULL值,而是至少存储这行的了主键值(rowid)
,在行头记录了一个位图来表示(ORACLE压根没有这行的ROWID信息)
01位图实际上就是 0000 0001 表示第一个字段为NULL,
那么使用索引就简单了,简单扫描相对的字段位图标示位1的就出来了。
所以官方文档才有:
For both BTREE and HASHindexes, comparison of a key part with a constant value is a range condition
when using the =, <=>, IN(), IS NULL, or IS NOT NULL operators.
这样的说法,这IS NULL 对ORACLE是不成立的。


最后我们来做一下测试来证明NULL位图这个字节是否对应的是字段顺序:
为了简单起见建立3个表
 create table test10 (a int,b int,c int,d int,primary key(a),key(b,c,d));
 create table test11 (a int,b int,c int,d int,primary key(a),key(b,c,d));
 create table test12 (a int,b int,c int,d int,primary key(a),key(b,c,d));
mysql> insert into test10 values(1,NULL,1,NULL);
Query OK, 1 row affected (0.02 sec)
mysql> insert into test11 values(1,1,NULL,NULL);
Query OK, 1 row affected (0.01 sec)
mysql> insert into test12 values(1,NULL,NULL,1);
Query OK, 1 row affected (0.01 sec)
对于key(b,c,d)来说
b是第一个字段NULL为0001,c为第二个字段NULL为0010,d为第三个字段NULL为0100
我们来看看这个字节,按照我们的推论第一个应该为0000 0101,第二个应该为0000 0110,第三个应该为0000 0011
也就是05,06,03
不出所料下面是二进制显示分别为:
05000010fff28000000180000001
06000010fff28000000180000001
03000010fff28000000180000001

可见推论正确。

下面终结一下2种数据库索引对NULL值处理的不同

1、ORACLE B+所以压根没有存储NULL行的ROWID,没有任何NULL信息。那么涉及到任何NULL的查询都不能使用索引
    (注意这里不包含文章开头那种组合索引,指的是B+单列索引,更不包含IOT表。
       今天在发这个文章的时候一哥们不知道为什么会扯到IOT,毕竟ORACLE中常用
      的HEAP TABLE这种无序的存储方式来存储数据,而不像INNODB本生就是IOT
       关于IOT参考我的博客:
       http://blog.itpub.net/7728585/viewspace-1820365/)
2、MYSQL INNODB 存储了NULL行的信息,至少主键是有的,但是NULL值的表示方法是使用一个BITMAP 位图字节(不一定是一个字节)
   位图字节的顺序代表了字段的顺序,所以使用is null可以使用到索引。

关于“ORACLE 索引和MYSQL INNODB 辅助索引对NULL的处理区别有哪些”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

您可能感兴趣的文档:

--结束END--

本文标题: ORACLE 索引和MYSQL INNODB 辅助索引对NULL的处理区别有哪些

本文链接: https://www.lsjlt.com/news/63098.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • ORACLE 索引和MYSQL INNODB 辅助索引对NULL的处理区别有哪些
    这篇文章将为大家详细讲解有关ORACLE 索引和MYSQL INNODB 辅助索引对NULL的处理区别有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 ...
    99+
    2024-04-02
  • mysql索引间有哪些区别
    本篇内容介绍了“mysql索引间有哪些区别”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
    99+
    2024-04-02
  • mysql主键和索引有哪些区别
    这篇文章主要为大家展示了“mysql主键和索引有哪些区别”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“mysql主键和索引有哪些区别”这篇文章吧。 ...
    99+
    2024-04-02
  • mysql中聚集索引和非聚集索引有哪些区别
    这篇文章主要介绍mysql中聚集索引和非聚集索引有哪些区别,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完! 区别:1、聚集索引在叶子节点存储的是表中的数据,...
    99+
    2024-04-02
  • MySQL中NULL对索引的影响有哪些
    小编给大家分享一下MySQL中NULL对索引的影响有哪些,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!在mysql5.6和5.7下均可,存储引擎为InnoDB。数据如下:1. 单列索引给n...
    99+
    2024-04-02
  • MySQL中的组合索引与单列索引的区别有哪些
    本篇内容介绍了“MySQL中的组合索引与单列索引的区别有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!...
    99+
    2024-04-02
  • Mysql搜索引擎都有哪些区别
    小编给大家分享一下Mysql搜索引擎都有哪些区别,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨吧! 一般MySQL常用的引擎有:ISAM,MyISAM,HEAP,InnoDB和Berkl...
    99+
    2024-04-02
  • Oracle与PostgreSQL的NULL和索引使用区别是什么
    这篇文章主要讲解了“Oracle与PostgreSQL的NULL和索引使用区别是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Oracle与Postgr...
    99+
    2024-04-02
  • MySQL单列索引和联合索引的知识点有哪些
    本篇内容主要讲解“MySQL单列索引和联合索引的知识点有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MySQL单列索引和联合索引的知识点有哪些”吧!一、简...
    99+
    2024-04-02
  • 主键与聚集索引的区别有哪些
    这篇文章主要讲解了“主键与聚集索引的区别有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“主键与聚集索引的区别有哪些”吧!主键(PRIMARY KEY )...
    99+
    2024-04-02
  • mysql的索引有哪些类型和特点
    mysql索引类型包含:1. b-tree 索引:快速等值、范围及前缀搜索;2. 哈希索引:快速等值搜索;3. 全文索引:模糊搜索文本字段;4. 空间索引:地理空间查询;5. 覆盖索引:...
    99+
    2024-04-22
    mysql 键值对
  • Oracle与MySQL删除字段时对索引和约束的处理方式
    本篇内容主要讲解“Oracle与MySQL删除字段时对索引和约束的处理方式”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Oracle与MySQL删除字段时对索引...
    99+
    2024-04-02
  • mysql中的键和索引相关知识点有哪些
    本篇内容介绍了“mysql中的键和索引相关知识点有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、主...
    99+
    2024-04-02
  • 了解ASP、索引、JavaScript和Unix:这些技术对您的工作有何帮助?
    作为现代工作的一份子,计算机技术的重要性不可忽视。在这个不断变化的时代,了解和掌握各种技术和工具对于提高工作效率和职业发展至关重要。在本文中,我们将重点讨论ASP、索引、JavaScript和Unix这些技术,以及它们如何对您的工作有所帮...
    99+
    2023-09-23
    索引 javascript unix
  • 有哪些 npm 工具包可以帮助 Python 更好地处理大数据索引?
    随着数据量越来越大,对于数据的存储和索引需求也越来越高。Python 作为一种非常流行的编程语言,为大数据处理提供了强大的支持。然而,当数据量达到一定规模时,Python 的默认数据结构可能会变得不够高效。这时,借助一些 npm 工具包可以...
    99+
    2023-08-23
    大数据 索引 npm
  • MySQL自适应哈希索引的特点和缺陷有哪些
    这篇文章主要讲解了“MySQL自适应哈希索引的特点和缺陷有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“MySQL自适应哈希索引的特点和缺陷有哪些”吧!...
    99+
    2024-04-02
  • PHP编程算法中的自然语言处理技术对于索引有何帮助?
    随着互联网的发展,数据量呈现爆炸式增长,如何高效地管理和检索数据成为了亟待解决的问题。为了提高数据的检索效率,人们开发了许多算法和技术,其中自然语言处理技术在索引方面发挥了重要的作用。 一、自然语言处理技术 自然语言处理(Natural ...
    99+
    2023-08-06
    自然语言处理 索引 编程算法
  • ORACLE MYSQL中join 字段类型不同索引失效的情况有哪些
    小编给大家分享一下ORACLE MYSQL中join 字段类型不同索引失效的情况有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下...
    99+
    2024-04-02
  • Java中的对象存储和索引技术有哪些值得关注的特点?
    Java作为一种广泛使用的编程语言,其对象存储和索引技术也备受关注。本文将介绍Java中值得关注的对象存储和索引技术的特点,并附上相应的演示代码。 对象存储技术 1.1. Java序列化 Java序列化是一种将Java对象转换为字节流的...
    99+
    2023-06-08
    对象 存储 索引
  • 应针对seo搜索引擎工作原理应该进行的优化有哪些
    今天就跟大家聊聊有关应针对seo搜索引擎工作原理应该进行的优化有哪些,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。应针对搜索引擎工作原理进行哪些优化? 1、关键词分析(核心词、扩展词...
    99+
    2023-06-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作