Oracle 中的 unique index 和 non unique index的区别

Oracle中Unique(id)和id int unique的区别 本文主要介绍的是Oracle中Unique(id)和id int unique的区别 阅读详情

今天做Schema评审的时候发现一个很奇怪的现象,也许是用工具生成的SQL语句,清一色的如下:

CREATE TABLE table_name (
    id          NUMBER          NOT NULL,
    ......
    ......
) ;
 
CREATE INDEX table_name_PK ON table_name(ID) ;
ALTER TABLE table_name 
  ADD CONSTRAINT table_name_PK PRIMARY KEY (ID) 
  USING INDEX table_name_PK ;

通常来说主键(Primary Key,PK)的index是unique index,而现在变成了non-unique index,这有什么不同呢?

于是我建了两张1000万数据的表,并用两种不同的index设定为PK的index,语句如下:

create table tab1000w01 
as
select level id,'killkill Hello world' data
from dual connect by level<=1000*10000;
 
create table tab1000w02 
as
select level id,'killkill Hello world' data
from dual connect by level<=1000*10000;
 
CREATE UNIQUE INDEX tab1000w01_pk ON tab1000w01 (PK_ID)  ;
ALTER TABLE  tab1000w01 ADD CONSTRAINT tab1000w01_PK PRIMARY KEY (PK_ID) USING INDEX tab1000w01_pk ;
 
CREATE INDEX tab1000w02_pk ON tab500w02 (PK_ID)  ;
ALTER TABLE  tab1000w02 ADD CONSTRAINT tab1000w02_PK PRIMARY KEY (PK_ID) USING INDEX tab1000w02_pk ;

以下是按照PK查找数据的语句:

select * from tab1000w01 where id=34567;
 
-------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                   |     1 |    35 |     3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TAB1000W01        |     1 |    35 |     3   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN         | IDX_TAB1000W01_PK |     1 |       |     2   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access("ID"=34567)
 
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          4  consistent gets
 
 
select * from tab1000w02 where id=34567;
 
-------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                   |     1 |    35 |     3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TAB1000W02        |     1 |    35 |     3   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX_TAB1000W02_PK |     1 |       |     2   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access("ID"=34567)
 
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          5  consistent gets

从执行计划来看,一个是index unique scan,一个是index range scan,从consistent gets来看,一个是4,一个是5,使用unique index节省了1个,不要少看这1个consistent gets,它可是占了总体的20%啊。

不过这是为什么呢?这篇文章很好地介绍这两种索引的异同:Differences Between Unique and Non-Unique Indexes,说到底是这两种索引的结构不同。引用一下这篇文章的分析:

Leaf block dump
===============
header address 143336028=0x88b225c
kdxcolev 0
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 500
kdxcofbo 1036=0x40c
kdxcofeo 1042=0x412
kdxcoavs 6
kdxlespl 0
kdxlende 0
kdxlenxt 75520140=0x480588c
kdxleprv 75520138=0x480588a
kdxledsz 0
kdxlebksz 8036
row#0[8022] flag: ------, lock: 0, len=14     <=== length is 14 bytes for the index row entry
col 0; len 4; (4):  c3 60 61 1c
col 1; len 6; (6):  04 80 50 3c 01 06         <=== rowid is stored as a second column for the index row entry
row#1[8008] flag: ------, lock: 0, len=14
col 0; len 4; (4):  c3 60 61 1d
col 1; len 6; (6):  04 80 50 3c 01 07

non-unique index将 rowid 作为一个字段和数据字段组合成一个“唯一、复合”索引

 

而unique index的结构如下:

Leaf block dump
===============
header address 143336028=0x88b225c
kdxcolev 0
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 1
kdxcosdc 0
kdxconro 533
kdxcofbo 1102=0x44e
kdxcofeo 1112=0x458
kdxcoavs 10
kdxlespl 0
kdxlende 0
kdxlenxt 75527436=0x480750c
kdxleprv 75527434=0x480750a
kdxledsz 6
kdxlebksz 8036
row#0[8023] flag: ------, lock: 0, len=13, data:(6):  04 80 5e 34 02 82    <=== length is 13 byes and rowid not stored as a second column entry
col 0; len 4; (4):  c3 60 30 2c
row#1[8010] flag: ------, lock: 0, len=13, data:(6):  04 80 5e 34 02 83
col 0; len 4; (4):  c3 60 30 2d

从dump文件中可以看到结构不同导致index中的entry的长度是不一样的,unique index稍稍短一点,所以每个block可以容纳更多的index entry,从宏观来看unique index更小一点。

 

不像 MySQL 唯一性约束是由唯一性索引实现,Oracle 的索引和约束是分开对待的。

如果某一天,需要将某个唯一性约束(Unique Key)变为不约束,unique index 只能删除重建了,一般变更的语句会变成这样:

create table table_xxx .......;

create index uk_xx on table_xx ( col ) online ;

# 以上实现了一个唯一性约束

# 突然来了一个需求,要将这个唯一性约束去掉,但是按 col 列查的语句海得跑 -_-

create index idx_xx on table_xx ( col , 'c' ) online ;

drop index uk_xx ;

create index idx_col on table_xx ( col ) online ; 

drop index idx_xx ;

没有看错,索引建两次和删索引两次,第一次建复合索引是因为 Oracle 不允许两个索引的索引列信息一致,只能加一个无关重要的东西卡位。

针对这种奇葩需求,使用 non unique index + unique constraint 更灵活:

create table table_xxx .......;

create index uk_xx on table_xx ( col ) online ;

alter table table_xx add constraint uk_xx unique( col ) using uk_xx ;

# 以上实现了一个唯一性约束


# 突然来了一个需求,要将这个唯一性约束去掉,但是按 col 列查的语句海得跑 -_-

alter table table_xx drop constraint uk_xx ;

从维护的角度来说,特别是大表的情况下,推荐第二种方式。

 

转载请注明出处: https://blog.youkuaiyun.com/killlkilll/article/details/97966651

 

数字IC设计避坑指南:为什么477条net的DRV问题无法修复?解析don‘t touch hierarchy的影响 本文深入解析了数字IC后端实现中,因“don't touch hierarchy”约束导致大量DRV违规(如477条net)无法自动修复的根本原因。文章以Cadence Innovus工具为例,详细阐述了DRV修复机制与设计保护约束的冲突原理,并提供了从日志定位、风险评估到分级解除约束的完整实战策略,帮助工程师有效解决此类设计收敛难题。 阅读详情

相关推荐

告别手动维护!教你用SAP BAPI批量更新生产订单BOM组件(CO02工单)

本文详细介绍了如何利用SAP BAPI实现生产订单BOM组件的批量更新,解决传统手工操作(如CO02工单)效率低下的问题。通过核心函数解析和批量处理框架设计,帮助用户大幅提升工作效率,降低错误率,适用于物料主数据变更、季节性配方调整等场景。

weixin_30844577的博客 561

05|Oracle学习(UNIQUE约束)

也叫:唯一键约束,用于限定数据表中字段值的唯一性。

技术小白=-=的博客 3875

Quantum Espresso Hands-On实战训练(四)——PDOS计算与轨道分析

本文详细介绍了Quantum Espresso中PDOS计算与轨道分析的实战方法,重点解析了PDOS在材料电子结构研究中的核心价值,包括原子级分辨率、轨道级解析和自旋极化分析。通过具体案例和操作步骤,帮助读者掌握从输入文件准备到结果解读的全流程,并提供了高级分析技巧和疑难问题解决方案。

weixin_29211309的博客 504

唯一性索引的意义

原文转自:http://blog.itpub.net/17203031/viewspace-700089/ 索引是我们经常使用的一种数据库搜索优化手段。适当的业务操作场景使用适当的索引方案可以显著的提升系统整体性能和用户体验。在Oracle中,索引有包括很多类型。不同类型的索引适应不同的系统环境和访问场景。其中,唯一性索引Unique Index是我们经常使用到的一种。   唯一性索引uni

万里晴空 9850

一分钟教会你搭建steam新游幻兽帕鲁服务器

总结: 游戏对服务器搭建要求相对较高、且对服务器网络协议有要求不能封堵UDP、多开、游戏运行久、同时在线人数多了这些会很吃内存 我自己用的64G内存多开4区测试玩家同时在线50多人的情况下内存已经跑满了、对于想用服务器搭建联机的小伙伴建议根据开区数量以及玩家人数去选择配置、当然也可以直接找我阿杰购买、我可以提供技术搭建服务。注:如果用的是本地电脑局域网搭建直接输入127.0.0.1:8211就行 如果用的是服务器搭建输入自己服务器IP+端口或解析的域名+端口进入游戏。

用最简单的方式说最重要的事!服务器、存储、云计 算、A智能的大数据产品、游戏开发技术。致力于广 大开发者、政企用户、各项机构等,构建云上世界提供全方位云计算解决方案。旨在打造差异化的开放式闭环生态系统帮助用户快速构建稳定、安全的云计算环境。 2234

Fluent Meshing边界层设置保姆级教程:从y+理论到实战避坑,看完就会

本文详细解析了Fluent Meshing边界层设置的全过程,从y+理论基础到实战避坑技巧,帮助用户精准计算第一层高度并优化参数配置。通过案例演示和常见问题诊断,指导读者掌握边界层网格生成的核心技术,提升CFD模拟精度。特别针对不同湍流模型的y+要求提供具体参数建议。

weixin_30576827的博客 784

Oracle之唯一性约束(UNIQUE Constraint)用法详解

Oracle | PL/SQL唯一索引(Unique Constraint)用法 1 目标 用示例演示如何创建、删除、禁用和使用唯一性约束。 2 什么是唯一性约束? 唯一性约束指表中一个字段或者多个字段联合起来能够唯一标识一条记录的约束。联合字段中,可以包含空值。 注:在Oracle中,唯一性约束最多可以有32列。 唯一性约束可以在创建表时或使用ALTER TABLE语句创建。 3 唯一性约束和主键的区别 主键(Primary Key):所有组成主键的列都不能包含空值。 唯一性约束(Uniqu

tanghuan0827的博客 5177

利用wolcmd.exe批处理执行远程唤醒

代码如下: @echo off cls :check if exist wolcmd.exe goto targetmac echo 缺少wolcmd.exe echo. goto end :targetmac cls echo -------------------------------------------------------- echo 目标主机PC-01地址:40235678A...

Chriseo的博客 6946

oracle 添加unique,oracle的unique约束

unique约束是唯一性约束,对于需要列类型应用程序会重复出现分歧值。您可以加入一个单独的列unique约束。能够加入多个列unique约束()。假设为多个列加入一个unique约束,仅仅须要保证这多个列的值不会所有同样就可以。在创建表时,为列加入unique约束。形式例如以下:column_name data_type [constraint constraint_name] unique或cr...

weixin_35775778的博客 5195

AI 生成测试报告:从 2 小时到 10 分钟

本文分享了AI在汽车电子测试报告生成中的应用案例。作者以某车企ECU测试项目为例,对比传统报告方式(每天2小时)与AI辅助方式(每天20分钟),效率提升83%。文章详细介绍了测试报告的核心要素(测试概况、结果、问题分析、发布建议)和不同类型报告(日报、周报、总结报告)的特点,并提供了从CANoe导出测试数据的Python解析脚本示例。通过AI自动化处理,大幅减少了测试工程师在报告整理上的时间投入,为汽车电子测试工作提供了实用效率提升方案。

小明的博客 443

第3.2.1章 Eigen代码实战:四元数赋值用法总结及与变换矩阵转换

Eigen库中四元数(Quaternion)的赋值方法解析:Quaterniond和Quaternion<double>本质相同,但Quaterniond是更简洁的别名。主要赋值方式包括直接构造(w,x,y,z分量、旋转矩阵或轴角)、赋值运算符和成员函数赋值。使用时需注意参数顺序、归一化处理和头文件包含,常见错误包括模板参数缺失和构造顺序错误。四元数广泛应用于旋转矩阵转换、姿态组合等场景,合理选择赋值方式能提高代码可读性和正确性。

行知SLAM 587

oracle唯一索引与非唯一索引的区别 UNIQUE INDEX,NON-UNIQUE INDEX

索引是我们经常使用的一种数据库搜索优化手段。适当的业务操作场景使用适当的索引方案可以显著的提升系统整体性能和用户体验。在Oracle中,索引有包括很多类型。不同类型的索引适应不同的系统环境和访问场景。其中,唯一性索引Unique Index是我们经常使用到的一种。 唯一性索引unique index和一般索引normal index最大的差异就是在索引列上增加了一层唯一约束。添加唯一性索引的数据列...

sod5211314的博客 4359

Python爬虫实战:美团外卖商家数据抓取与分析

随着互联网技术的快速发展,外卖平台已成为人们日常生活中不可或缺的一部分。本文基于Python爬虫技术,使用最新的异步爬虫框架和反爬虫绕过技术,实现了对美团外卖平台商家信息与评分数据的自动化抓取。通过对抓取数据的清洗、存储和分析,为餐饮行业市场研究和商业决策提供数据支持。本文详细介绍了爬虫的设计思路、技术实现方案、数据处理方法以及可视化分析结果,为相关领域的研究者和开发者提供参考。关键词:Python爬虫;美团外卖;数据抓取;数据分析;异步爬虫。

2201_76125261的博客 1821

unique index与non-unique index的dump区别

10.2.0.5 on windows 2008  ASSM LMT  8K block non-u

loryliu的专栏 1983

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

oracle-index unique scan 与index range scan等的区别

存取Oracle当中扫描数据的方法(一)Oracle 是一个面向Internet计算环境的数据库。它是在数据库领域一直处于领先地位的甲骨文公司的产品。可以说Oracle关系数据库系统是目前世界上流行的关系数据库管理系统,本文将对oracle当中扫描数据的存取方法进行介绍。1) 全表扫描(Full Table Scans, FTS)为实现全表扫描,Oracle读取表中所有的行,并检查每一行是否满足语...

xiaocai9999的专栏 1672

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

oracle index unique scan/index range scan和mysql range/const/ref/eq_ref的区别

关于oracle index unique scan/index range scan和mysql range/const/ref/eq_ref type的区别 关于ORACLE index unique scan和index range scan区别在于是否索引是唯一的,如果=操作谓词有唯一索引则使用unique s...

weixin_34272308的博客 189

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

mysql中index和range区别,oracle index unique scan/index range scan和mysql range/const/ref/eq_ref的区别...

关于oracle index unique scan/index range scan和mysql range/const/ref/eq_ref type的区别关于ORACLE index unique scan和index range scan区别在于是否索引是唯一的,如果=操作谓词有唯一索引则使用unique scan否则则使用range scan但是这种定律视乎在MYSQL中不在成立如下执行...

weixin_39605296的博客 601

index的结构,non-unique index及unique index在row piece上存放的一些区别

index的结构,non-unique index及unique index在row piece上存放的一些区别: non-unique index:kdxledsz 0 --bytes in rowid datarow#0[...

cnpr8794的博客 288

Oracle 唯一 约束(unique constraint) 与 索引(index) 关系说明

一. 官网对Unique Constraints说明 http://download.oracle.com/docs/cd/E11882_01/server.112/e16508/datainte.htm#CNCPT1642 uniquekey constraint requires that every value in a column or set of columns beuniqu...

qjoycn 863

index block internal tips

index block和data block一样都是属于06类型的block(参考http://ningoo.itpub.net/post/2149/277126),所以两者的格式基本上相差不大,头部都是20字节的cache h...

congzhan1377的博客 258

Unique and Nonunique Indexes (195)

Indexes can be unique or nonunique. Unique indexes guarantee that no two rows of atable have duplicate values in t...

cneo2012的博客 208

powerdesigner 设置唯一约束

作者:yan

xyzroundo的专栏 1222
上一篇: dubbo-keeper CPU 耗尽分析
killlkilll
博客等级 码龄20年 14粉丝 49原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值