当前位置:首页 > 物联网 > 《物联网技术》杂志
[导读]摘 要:随着信息化的不断深入发展,数据的量呈现出几何级增长。而伴随着数据量的不断攀升,如何提高对数据库的访问性能成为每个信息系统的重点优化方向。索引技术是数据库性能优化中最常用的技术手段。以目前最流行的Oracle数据库为例,对数据库中索引的使用进行重点说明和举例,使读者对SQL语言中的索引技术有较深的了解。

引 言

在DBMS 中,索引是访问数据库中数据的重要手段,特别是在大型系统中,更是必备方法。如果说数据库是一本字典, 其中的数据是字典的内容,那么,索引就是这本字典的目录。查字典可以使用偏旁部首、汉语拼音、笔画等不同的方法进行查找,查询数据库中的数据也有各种各样的索引可供使用。在数据库中,索引使用DML 操作可以迅速找到表数据,不用对整张表逐行访问。索引是一种结构很强的方案对象,它将数据和存放数据的位置对应起来。对于数据量非常大的表来说,通过全表扫描来访问和通过索引来访问,速度可能有是数量级上的差别。

索引能通过事先保存的索引键,按照一定顺序记录数据的位置,由此替代 DML 操作原本要进行的全表扫描,通过“以空间换时间”的方法,牺牲少量的存储空间,换取快速的反应时间。在一张表上是否该建立索引、建立怎样的索引、怎样才能有效利用建立起的索引是数据库优化中最常见的问题。

1 SQL语句的执行过程

是否会使用索引要从Oracle 执行查询的机制开始分析。在Oracle 进行必要的语法检查和语义分析之后,会自动对语句进行优化,其目的就是找到最高效的运行路径。可能会使用的优化器有两种 :RBO 基于规则的优化器,CBO 基于成本的优化器。默认情况下是 CBO 优化器,它会快速统计数据量的大小,选择开销最小(尽量消耗最少的 CPU 和I/O)的执行计划。确定了执行计划之后,Oracle 会将SQL 语句格式化为内部执行代码。

由此可见,想要提高SQL 语句的性能,就要从优化器会选择怎样的执行计划这块考虑。如果表上没有建立索引,执行计划就是全表扫描,它会根据PGA 中的系统设定,读取一批数据块,如果表数据较小,全表可以一次性全部读入 ;如果数据量很大,则需要多次读取数据块。如果在数据量稍大的表上建立了索引,优化器会比较利用索引和全表扫描的读取数据次数,如果利用索引代价小,则选择利用索引,否则还是选择全表扫描。一般来说,查询语句要读取 10% 以上的数据量的话,优化器就宁愿选择全表扫描,而不是索引。因为一个索引项指向了一个数据块,所要读取的数据块太多,就有大量的I/O 操作要进行,反而降低性能。

2 索引的分类

建立怎样的索引。常见的索引有以下几种 :B* 索引(包含唯一索引),位图索引,函数索引,本地前缀分区索引,全局范围分区索引等。

(1) B*树索引

B* 树索引就是利用建立B 树,将索引列和指向表中各行的 rowid 组织起来,按照顺序建立一颗平衡树,根据索引列的数量,自动建立合理高度的B 树。在B 树索引中,所有叶子的深度一样,结构自动保持平衡,在增删改之后都由Oracle 自动维护。更重要的是,B 树索引可以适应多种查询条件,包含范围查找 >、<、>=、<=、like 和完全匹配。由于树的高度是基于索引列的数量,当访问的数据量占总数据的 10% 以上的时候,需要访问 B 树的范围太大,这个时候,其优势无法体现。

(2) 位图索引

当某一列上的值可选择性较低的时候,一般使用位图索引。所谓的“可选择性”就是指查询这一列的 distinct 值与这一列所有值的比例,这个比值越高,说明可选择性越高。对于“性别”列,只存在两种值,可选择性低 ;“姓名”列,可选择性一般较高。

(3) 函数索引

通过在某一列上利用函数来创建索引。例如 :createINDEX idx_func_sub on emp substr(empno,1,2);就是利用substr 函数,在empno上建立索引。

3 使用索引的方法和技巧

(1) 对于索引的建立,我们一般选择在可选择性高的列上建立索引。以地税系统的一张登记表为例,这张表记录了纳税人的登记信息,一个纳税人识别号对应一条记录,纳税人所属的区县对应字段dwid。在识别号 sbh和区县 dwid上分别建立索引IDX_SWJ_SBH和IDX_SWJ_dwid。如果有查询语句:

select * from glfw_swdj_tempwyp where sbh=’12345’ and dwid=’54321’;

查看执行计划如图 1所示, 执行计划没有使用IDX_ SWJ_dwid,因为sbh列的可选性要远高于dwid字段。

图1在SBH和DWID上建立索引后的执行计划

(2) 如果查询条件中包含多列,则在多列上建立复合索引效果更好。还是以上面的 SQL语句为例,glfw_swdj_ tempwyp 表上,建立基于sbh和dwid 的复合索引

create index IDX_SWJ_SBH_DWID on GLFW_SWDJ_ TEMPWYP(SBH,DWID);

这个时候,新的执行计划如图 2 所示。此时,利用条件语句中的两列复合索引,显然要比单一索引效率高。

图 2建立符合索引的执行计划

(3) 在建立复合索引的时候需要注意,复合索引的列的顺序很重要,最好依据各列的可选择性,由高到低排序。这样,通过B索引树进行访问的时候,由复合索引的第一列就能过滤掉更多的数据,使得I/O地读取更小。有些观点认为, 如果在 SQL语句中没有使用复合索引的前导列,则查询不会利用这个复合索引。这种说法是错误的。Oracle对于索引的访问分为索引唯一扫描(indexuniquescan)、跳跃式索引扫描(index skip scan)、索引范围扫描(index range scan)、索引全扫描(index full scan)等多种方式。就算条件语句中没有利用前导列,跳跃式索引扫描(index skip scan)依然起效。这种访问方式,通过将前导列分为各个不同的区域,在各区域内部使用复合索引的剩余部分来访问数据,最后将各个区域内符合条件的数据做union 操作,得出结果集。

(4) 对于多表连接时,需要建立复合索引的情况下,首先要判断驱动表和被驱动表。驱动表就是查询范围较少的表, 以它作为嵌套连接 nested loops 的外层循环,被驱动表作为内存循环。执行时,从驱动表中选取一个结果,与被驱动表匹配, 匹配上的就并入结果集,再选取驱动表的下一个结果,依次往后。这个时候,可以在被驱动表的连接字段和该表的其它约束条件上建立复合索引,这样,就能提高内层循环的效率。以地税局的应征表为例,当应征表(数据量很大)与税种代码表(数据量很小)发生关联时,税种代码表 dm_shuizhong_ wyp 是驱动表,在应征表上建立关联字段(szdm)和其它约束字段(szpq)的联合主键,还在应征表上建立 szdm 的单一主键,查看执行计划,发现优化器选择的是复合索引,如图 3 所示。

图 3 在表连接的连接字段上建立复合索引

对于建立的索引,在编写SQL 的时候要注意条件语句的写法,以免索引不被使用:

(1)在 where 条件中对索引列使用了函数,导致不能使用索引。

例如 在 应征 表 上 对 glbm 建 立 索引 INX_YZTEST_ GLBM,比较使用substr 函数的区别。

使用函数后如图 4 所示。

图 4 在索引字段上使用了函数时的执行计划

没有使用函数的如图 5 所示。

图 5 没有在索引字段上使用函数的执行计划

很明显,对索引所在的列使用函数,会导致索引无法使用。引起索引失效的函数还有decode、instr 等。索引如果真的要在条件语句中添加某些函数操作,可以在等号的另一边使用带“%”的模糊匹配,如图 6 所示。当然,由此也可以看见,使用like 的模糊匹配对索引的利用并没有完全匹配,原因也是显然的,查询的范围更大,匹配的结果更多。

图 6 在等号的另一边使用模糊匹配

但是,模糊匹配的时候“,%”不要加在匹配字符串的开始,否则索引仍然不起效,如图 7 所示。

图 7 将“%”放在模糊匹配的前端,无法利用索引

这是因为,模糊匹配过程中,索引会按照顺序采取“部分” 匹配原则 :先选择首字符为“1”的进行匹配,再在结果中选择第二个字符为“2”的继续匹配……但是如果模糊匹配一开始就要用“%”,则相当在最开始,所有结果都匹配上了,这时候索引就“罢工”了。

(2)在写SQL 语句的时候,要注意所比较的是字符串还是数字,例如,glbm 的字段类型是 char,如果在条件语句中将它与 54321 而不是‘54321’比较,则 Oracle 会通过内部转换, 将整个SQL 变为 :select a.* from sb_yzss_temp_wyp a where TO_NUMBER(a.glbm)>54321,由此,导致在索引列利用了函数,索引失效:

select a.* from sb_ yzss_temp_wyp a where a.glbm

>54321 ;

对于建立在数字类型字段上的索引,在条件语句中不要对数字字段进行算术运算,否则可能导致索引失效,例如在应征表的 nse 这个数字类型字段上建立索引,没有对 nse 进行算术运算时,索引可用:

selecta.*fromsb_yzss_temp_wypawhere a.nse>10000000.00

一旦加上了算术运算,索引就失效了:

select a.* from sb_ yzss_temp_wyp a where a.nse*1>10000000.00

(3)IS NULL 和 IS not NULL 的逻辑比较,也会导致索引失效。

4 结 语

索引不是越多越好,建立索引要遵循以下两点:

(1) 不需要为小表建立索引,这种表还不如采用全表扫描,先读索引再根据索引读数据反而麻烦;

(2) 根据具体的业务需求,只在经常使用的列上添加索引,根据可选性的不同,在可选择性高的列上建立 B树索引(例如员工编号字段),在可选择性较小的列上建立位图索引(例如性别字段),不常使用的列可以不建立索引。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

科睿唯安《全球创新Top100》以该公司拥有的专利数据库为基础,根据“成功率”、“地域投资”、“影响力”、“稀缺性”四个评价维度对知识产权进行分析,评选出全球百强创新企业和机构。该评选从2012年开始每年实施一次,202...

关键字: 数据库 5G 人工智能

北京——2024年2月26日 日前,领先的IT市场研究和咨询公司IDC发布《IDC MarketScape:全球云计算和以应用为中心的市场供应商评估》1报告,亚马逊位列“领导者”类别。报告指出,“亚马逊云科技Market...

关键字: 云计算 数据库 存储

北京——2023年12月27日 在2023亚马逊云科技re:Invent全球大会上,亚马逊云科技表彰了在过去一年中,利用亚马逊云科技的技术和服务在推动客户创新及解决方案构建方面做出杰出贡献的卓越合作伙伴。8家亚马逊云科技...

关键字: 数智化转型 机器学习 数据库

北京——2023年12月7日 亚马逊云科技在2023 re:Invent全球大会上,宣布推出三项新的无服务器服务创新,涵盖了数据库和分析领域,使客户能够更快速、更轻松地扩展他们的数据基础设施,以支持最具挑战性的应用场景。...

关键字: 服务器 人工智能 数据库

北京——2023年12月4日 亚马逊云科技在2023 re:Invent全球大会上,宣布推出一系列新的集成解决方案,旨在帮助客户迅速而轻松地连接和分析数据,而无需构建和管理复杂的提取、转换和加载(ETL)数据管道。通过全...

关键字: 数据存储 数据库 人工智能

北京——2023年11月13日 亚马逊云科技携手凯捷(Capgemini)中国共同发布《汽车行业可持续发展白皮书》(以下简称《白皮书》),并助力凯捷中国推出碳排放管理平台,致力于以数智化方式帮助车企解决在实践可持续发展过...

关键字: 数据库 机器学习 电动汽车

11月1日,由开放原子开源基金会主办,电子科技大学承办,深圳市腾讯计算机系统有限公司提供战略合作支持的2023年开放原子校源行(成都站)活动在电子科技大学圆满举行。本次活动以“聚缘于校,开源共行”为主题,将四川省在信息技...

关键字: 开源模式 操作系统 数据库

11月1日,2023杭州云栖大会上,阿里云瑶池数据库宣布已全面实现Serverless化,并接入通义等大模型能力,大幅提升数据库一站式及智能化水平。同时,PolarDB Always On系列推出3大重磅升级,首个数据智...

关键字: Serverless AI 阿里云 数据库

北京2023年9月8日 /美通社/ -- 日前,"云融数智 创领未来"2023浪潮云海云图生态峰会产品技术伙伴专场在北京成功举办。来自开源基金会、云安全、PaaS、数据库服务、容灾备份等领域的头部领先...

关键字: 云安全 私有云 数据库 NI

北京2023年9月7日 /美通社/ -- 在欧盟推出碳边境调节机制(CBAM)的背景下,为了更好的提升中国相关工业企业在碳排放管理方面的能力,推进中国与欧盟相关机制的国际合作,2023年9月3日于北京,DEKRA德凯受国...

关键字: 供应链 可持续发展 ISO 数据库
关闭
关闭