百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

应用最广的两类数据库的区别、优势对比、查询优化方法及案例实践

moboyou 2025-03-04 11:23 59 浏览

  1、通用数据库分类

  1.1关系型数据库

  关系型数据库是多个二维数据表的集合,数据以二维数据表的形式进行存储,数据表之间可以通过应用程序或者数据的主、外键建立特定的关联关系,让数据之间存在特定的应用联系。他的优点主要是数据访问简便,通过结构化查询语言SQL进行单一数据表或多数据表的联合查询、修改和删除操作。相较于非关系型数据库,对于大规模的数据的读写操作效率不高。

  1.2非关系型数据库

  非关系型数据库是各种存储方式的集合,存储形式包括图像、文本等,它不以关系型数据表的形式储存。他可以使用专用的硬件设备提升大规模数据的读写效率,通常被用作分析性场景。

  2、常用关系型数据库查询过程原理

  对于关系型数据库来说,不管是MYSQL、ORACLE还是DB2其数据库的查询过程通常都分为5个步骤,以DB2为例其包括语法和语义检查、选择最优访问路径、生成数据库可识别的执行代码、按SQL命令进行数据操作等。下面以DB2为例对上述过程进行详细的介绍。

  1)Precompile

  Precompile是DB2的预编译,由于大部分的编译器不能识别SQL 语句,需要在执行编译(COMPILE)之前使用DB2的预编译器防止编译器在编译过程中出错。其中数据库会将程序分离成2部分。一部分是数据库从应用程序中剥离出的应用逻辑部分,我们称之为LOAD MODULE,该文件用作后续的COMPILE;另一部分是SQL语句,我们称之为DBRM,这部分就是我们执行数据库操作的代码。LOAD MODULE与DBMR通过token进行关联,保证两部分内容在应用执行时可以完美的匹配。

  2)cics translation

  该部分数据库会对cics相关的执行进行解析和转义,以保证在编译阶段数据库对cics相关指令可以识别

  3)Compile

  该部分数据库编译器会分析源程序并将源码翻译成机器指令,SQL的语义与语法检查都是通过该部分进行。

  4)访问路径选择

  该部分是数据库对sql语句的访问路径进行择优选择,该部分通过数据库的optimizer完成,实际工作会在Compile阶段一并完成。

  3、优化器最优访问路径选取原则

  以DB2为例,数据库通过optimizer进行访问路径的选择,通常我们所说的sql语句优化大部分都是对查询语句的优化。数据库在执行一条sql语句的时候可以通过多条道路实现一条数据的读取功能,比如对于同一条记录的查询,数据库可以通过索引进行数据的筛查,我们称之为index scan 或者index only。对于多索引的数据表来说,针对不同的索引,访问路径又有多条道路可以选择。又或者数据库也可不使用索引而是通过全表扫描的方式进行数据读取。那么最终数据库会选择何种路径进行数据读取操作呢?这个就是最优访问路径的选择问题。

  数据库优化器最优访问路径选取的方法并不复杂,其内部有一套标准的算法,首先数据库会将所有可获取到需求数据的访问路径进行读取成本的估算。并对所有路径估算出的开销进行比较,选择开销最小的作为这一条数据访问语句的最优访问路径以达到提升访问效率的目的。

  影响访问路径选择的因素有很多,包括数据表的索引建立方式,如唯一索引、主键、分区索引、非分区索引、cluster index和非cluster index等等。同时数据表数据的摆布方式,包括数据表键值的重复率等等也对访问路径的选择起到很大的作用,甚至执行sql语句数据库所在的硬件设备容量也在访问路径选择的考量之中。

  数据库最优访问路径的选取实际上就是访问开销最小的访问路径的选取,目的是降低sql语句执行时候的cpu和磁盘I/O的消耗,提升访问效率。

  4、高效查询语句书写原则

  4.1避免不恰当的使用“SELECT *”

  如果 SQL 语句使用了“SELECT *”,DB2 就需要把表的所有列都进行处理并且返回给用户,这显然会增加 I/O 和 CPU 的开销。如果这条 SQL 语句还包括了排序(Sort)操作(比如 ORDER BY),那么对全部这些列进行排序也会影响到性能。而且当表定义的列越多,每个列定义的数据类型(Data type)长度越长,这对性能的影响就可能越明显。

  4.2避免在本地谓词的列上使用复杂表达式

  本地谓词(Local predicate)是与连接谓词(Join predicate)相对应,它一般是指该谓词当中只包含一个表上的一个列。YEAR(Date) > 2004 和 Amount > 1000 都是两个本地谓词。然而在前一个谓词 YEAR(Date) > 2004 中,它对 Date 这个列有一个函数 YEAR 的调用。在这种情况下,即使 Date 上存在一个索引,DB2 也无法使用这个索引来访问数据。如果能够在确保语义不变的前提下,适当改写这个谓词,避免在 Date 列上调用函数,那么情况可能会有所不同。例如,这个谓词可以改写为如下的样子:

Date > ‘ 2004-12-31 ’

  下面来看一个具体的示例:

SQL 1:select l_quantity, l_comment from lineitem

  where l_orderkey + 100 = 200

  SQL 2:select l_quantity, l_comment from lineitem

  where l_orderkey = 100

  SQL 1 的访问路径图

  

SQL 2 的访问路径图

4.3避免用复杂表达式构建连接谓词

  让数据库可以有多种访问路径的选择,避免由于人为编写不恰当的SQL语句限制优化器的选择。

  T1.C1=T2.C2 就是一个典型的连接谓词,这种写法也是常见的连接谓词的形式。对于这种常见的连接谓词,DB2 可以考虑采用几种不同的表连接方式(Join Method),常见的连接方法有嵌套循环连接(Nested-Loop-Join, NLJ),归并排序连接(Merge-Scan-Join, MSJoin),哈希连接(Hash-Join)等。DB2 优化器会根据实际情况选择从中选取一个性能最佳的来将 T1 和 T2 连接起来。

  但是在连接谓词 T1.C1 * T1.C2 = T2.C2 中,“=”左边不是一个列名,而是一个表达式,它涉及 T1 表上不同列之间的计算。对于这样一个用复杂表达式构建的连接谓词,DB2 只能用 Nested-Loop-Join 这种最基本的方式来建立 T1 和 T2 之间的连接,而不考虑用其他的连接方式,从而也就无法选择最优的连接方式。

  看下面这个示例:

SQL 1:

  SELECT l_comment, o_comment FROM lineitem, order

  WHERE l_orderkey = o_orderkey + 100

  SQL 2:

  SELECT l_comment, o_comment FROM lineitem, order

  WHERE l_orderkey = o_orderkey

SQL 1 的访问路径图

SQL 2 的访问路径图

  如果想在满足业务逻辑需求的情况下,同时保证连接谓词的简洁,也可以考虑增加一个新的列(例如 SQL 1 中,定义新的列 o_orderkey2,其值等于 o_orderkey + 100),直接构造连接谓词(l_orderkey = o_orderkey2),从而最大程度的提高 SQL 语句的性能。

  4.4避免连接谓词中的数据类型不一致

  在用连接谓词连接不同的表的时候,即使对于 T1.C1=T2.C1 这样典型的连接谓词,也应该确保 T1.C1 和 T2.C1 具有同样的数据类型。连接谓词中两个列的数据类型定义的不一致会导致 DB2 放弃使用某些表连接方式。比如 Hash-Join 这种表连接方式对连接谓词就有更多的限制条件,条件之一就是连接谓词中的两个列的数据类型必须完全一致,否则 Hash-Join 不能使用。此外,如果 T1.C1 的数据类型是 CHAR,GRAPHIC,DECIMAL 或者 DECFLOAT,那么 T2.C1 除了需要是相同的数据类型外,它所定义的数据类型的长度也需要和 T1.C1 一致。更多的表连接方式意味着 DB2 可以有更多的选择来将表连接在一起,并从中选出最优的方案。

  看下面这个示例:

SQL 1: SELECT l_comment, o_comment FROM lineitem, order

  WHERE l_orderkey = o_orderkey

  对于 SQL 1,DB2 优化器采用了归并排序 (MSJoin) 的连接方法对两个数据表进行了连接操作 ,这里连接谓词 l_orderkey = o_orderkey 中的 2 个列的数据类型完全一致都为 integer 类型。如果改动其中一个列的数据类型为 double 类型,此时 DB2 就只能采用嵌套循环连接方法进行连接操作,而对比之后就会发现,使用嵌套循环连接的 Total Cost 较高,这意味着性能较差。

  INTEGER = INTEGERINTEGER= DOUBLE


  4.5确保在连接谓词中使用等号

  典型的连接谓词通常是形如 T1.C1=T2.C1 这样的形式,注意到这里是用“=”这个操作符将左右两边的列连接起来。理论上,也可以使用其他的操作符来构造连接谓词,比如“<”或者“>”这样的比较运算符。但是实际上基于性能的考虑,在连接谓词中应该只使用“=”,尽量避免使用其他的比较运算符。

  在连接谓词 T1.C1 < T2.C1 中,使用了“<”这个比较运算符。 对于这样的 SQL 语句,DB2 只能采用 Nested-Loop-Join 这种最基本的方式来建立 T1 和 T2 之间的连接,而不考虑用其他的连接方式。在某些实际的应用场景当中,出于业务逻辑上的要求,出现 T1.C1 < T2.C1 这样的连接谓词可能是不可避免的。在这种情况下,基于性能优化的考虑,应该在 T1 和 T2 上都建立适当的索引,使得 T1.C1 < T2.C1 这个谓词能够使用索引。其中的原因在于,DB2 只能使用 Nested-Loop-Join 来建立 T1 和 T2 之间的连接,此时应该确保有合适使用的索引能够让 Nested-Loop-Join 采用 Index-Scan 这种数据访问方法,从而尽可能提高性能。

  看下面的示例,

SQL 1: SELECT l_comment, o_comment FROM lineitem, order

  WHERE l_oderkey >o_orderkey

  SQL 2: SELECT l_comment, o_comment FROM lineitem, order

  WHERE l_oderkey =o_orderkey

  在 SQL 1 中连接谓词是通过大于号连接的,DB2 只能采用嵌套循环连接 (Nested-Loop-Join) 这种最基本的方式来建立两个表之间的连接。在 SQL2 中连接谓词中采用“=”连接,此时 DB2 优化器选用了归并排序(MSJoin)的连接方式,它的 Total cost 比 SQL 1 的要低很多,具有较好的性能。注意这里 SQL 1与 SQL 2 在语义上是不等价的,在这里用这样的示例是为了说明连接谓词中不使用等号的写法会导致访问路径完全不同,从而影响查询性能。

  SQL 1 的访问路径图

SQL 2 的访问路径图

  4.6恰当安排 Group By 子句中列的顺序

  通常情况下,SQL 语句中的 GROUP BY 子句会导致数据库不得不通过一个排序(SORT)操作来实现对数据的分组,而排序被认为是一个比较耗费 CPU 和内存的操作。实际上某些情况下,如果写法得当,当中的排序操作是可以避免的。具体来说,在写 GROUP BY 子句的时候,应该考虑到数据库中已经存在的索引的情况。如果 GROUP BY 子句中所有的列恰好包括在某个索引的键(Key column)的范围之内而且是处于开始的位置,那么在写 GROUP BY 子句的时候,就应该按照该索引上键的先后顺序来写 GROUP BY 子句。

  比如说有如下的 SQL 语句:

SELECT C2, C3, C1, AVG(C4)

  FROM T1

  GROUP BY C2, C3, C1

  一般情况下,GROUP BY C2, C3, C1这样的写法都会导致数据库的一个排序操作。但假定表 T1 上已经存在一个索引 IX1(C1, C2, C3, C4), 这里注意到 GROUP BY 子句中引用到的列(C2,C3,C1)正好是索引 IX1 中的前三个键,那么就可以通过改变 GROUP BY 子句中列的顺序的办法来避免这个排序操作。

  可以把 SQL 语句改写为如下所示:

SELECT C1, C2, C3, AVG(C4)

  FROM T1

  GROUP BY C1, C2, C3

  通过这样改变 GROUP BY 子句中列的顺序使其与索引 IX1 中的键顺序一致,数据库就可以利用 IX1 来访问其已经排序的键值并直接返回进行下一步操作,从而避免额外的排序操作,从而带来查询性能上的提高。

  需要指出的是,通过这样改写 GROUP BY 子句来避免排序,可能会导致最终返回结果的顺序不一致。在实际的业务逻辑当中,需要用户来确认是否其关注返回结果的顺序性。

  下面来看一个具体的示例:

SQL 1:SELECT AVG(o_shippriority) FROM order

  GROUP BY o_custkey , o_orderkey, o_orderdate

  SQL 2:SELECT AVG(o_shippriority) FROM order

  GROUP BY o_orderkey, o_orderdate, o_custkey

  这里 2 个 SQL 唯一的差别就在于 GROUP BY 子句中列的顺序不同。假定order 表上存在一个索引 PXO@OKODCKSPOP (O_ORDERKEY,O_ORDERDATE,O_CUSTKEY,O_SHIPPRIORITY,O_ORDERPRIORITY)。

  由于 SQL 1 中的 GROUP BY 子句的列顺序与索引 PXO@OKODCKSPOP 的键顺序不一致,DB2 无法直接利用这个索引,所以 DB2 需要基于这 3 个列做一次排序(Sort),然后进行分组合并,排序的结果还需要通过临时文件(Wkfile)来保存。如果调整 GROUP BY 子句中的列顺序如 SQL 2 所示,使其与索引 PXO@OKODCKSPOP 的键顺序一致,DB2 通过这个索引返回的结果就已经是有序的,这样就省去了排序操作。对比两者的访问路径图可以看出来,SQL 2 所花费的成本(Total Cost)会少很多,性能上有较大的提高。

  SQL 1 的访问路径图

SQL 2 的访问路径图

  4.7活用FETCH FIRST N ROWS ONLY字句

  在 DB2 的 SQL 语法中,FETCH FIRST n ROWS ONLY 表示只取回结果集当中的前 n 条记录,在应用中经常会碰到判断满足条件的数据是否存在这样的逻辑,为达到目的有些程序员会用count(*)的结果来作为判断依据,众所周知count(*)的性能是不高的,对于此类场景可以考虑用FETCH FIRST 1 ROWS ONLY替代。

  4.8多用indexable 谓词避免使用Non-indexable谓词

  indexable的布尔类型谓词才能成为用来匹配索引的谓词,而Non-indexable的谓词是不能用来匹配索引的,在谓词设计中,首先需要应用的基本原则是尽量避免使用Non-indexable 谓词。

  Non-indexable谓词包括:

  1)谓词左边的列在表达式或函数中 DATE + 10 < CURRENTDATE, LENGTH(C1) = 4

  2)与字段比较的对象是不同类型的值或变量,如变量定义与字段类型不符。

  3)字段之间的比较 C1 < C2

  4)BETWEEN col1 AND col2

  5)非谓词,即包含NOT,NOT NULL,NOT LIKE,NOT IN,NOT BETWEEN,<>

  6)LIKE谓词使用时将通配符放在最前面。C1 LIKE ‘%ABC’

  4.9谓次匹配尽量多的索引字段

  一个查询语句谓词与索引的key column匹配越多,过滤率越高,查询的效率也越好。

  4.10谓词中加入分区表分区键值

  对于分区表而言,尽可能在SQL语句中加入分区键值列作为谓词,将查询范围限定在某一个或某几个分区中,避免整表扫描,可以极大地减少I/O开销。

  5、总结

  本文主要介绍了当下使用最广泛的两类数据库(关系型数据库及非关系型数据库)的区别和各自优势进行了简要阐述。从农行核心应用实际出发,重点从开发人员角度,对关系型数据库查询语句的书写与数据库访问性能的关系进行了阐述,通过实例给出了高效SQL语句的书写方法及背后的技术原理。

请关注+私信回复:“测试”就可以拿到测试开发8大进阶技术图谱及软件测试免费学习资料包,快速让自己变强!

相关推荐

Excel技巧:SHEETSNA函数一键提取所有工作表名称批量生产目录

首先介绍一下此函数:SHEETSNAME函数用于获取工作表的名称,有三个可选参数。语法:=SHEETSNAME([参照区域],[结果方向],[工作表范围])(参照区域,可选。给出参照,只返回参照单元格...

Excel HOUR函数:“小时”提取器_excel+hour函数提取器怎么用

一、函数概述HOUR函数是Excel中用于提取时间值小时部分的日期时间函数,返回0(12:00AM)到23(11:00PM)之间的整数。该函数在时间数据分析、考勤统计、日程安排等场景中应用广泛。语...

Filter+Search信息管理不再难|多条件|模糊查找|Excel函数应用

原创版权所有介绍一个信息管理系统,要求可以实现:多条件、模糊查找,手动输入的内容能去空格。先看效果,如下图动画演示这样的一个效果要怎样实现呢?本文所用函数有Filter和Search。先用filter...

FILTER函数介绍及经典用法12:FILTER+切片器的应用

EXCEL函数技巧:FILTER经典用法12。FILTER+切片器制作筛选按钮。FILTER的函数的经典用法12是用FILTER的函数和切片器制作一个筛选按钮。像左边的原始数据,右边想要制作一...

office办公应用网站推荐_office办公软件大全

以下是针对Office办公应用(Word/Excel/PPT等)的免费学习网站推荐,涵盖官方教程、综合平台及垂直领域资源,适合不同学习需求:一、官方权威资源1.微软Office官方培训...

WPS/Excel职场办公最常用的60个函数大全(含卡片),效率翻倍!

办公最常用的60个函数大全:从入门到精通,效率翻倍!在职场中,WPS/Excel几乎是每个人都离不开的工具,而函数则是其灵魂。掌握常用的函数,不仅能大幅提升工作效率,还能让你在数据处理、报表分析、自动...

收藏|查找神器Xlookup全集|一篇就够|Excel函数|图解教程

原创版权所有全程图解,方便阅读,内容比较多,请先收藏!Xlookup是Vlookup的升级函数,解决了Vlookup的所有缺点,可以完全取代Vlookup,学完本文后你将可以应对所有的查找难题,内容...

批量查询快递总耗时?用Excel这个公式,自动计算揽收到签收天数

批量查询快递总耗时?用Excel这个公式,自动计算揽收到签收天数在电商运营、物流对账等工作中,经常需要统计快递“揽收到签收”的耗时——比如判断某快递公司是否符合“3天内送达”的服务承...

Excel函数公式教程(490个实例详解)

Excel函数公式教程(490个实例详解)管理层的财务人员为什么那么厉害?就是因为他们精通excel技能!财务人员在日常工作中,经常会用到Excel财务函数公式,比如财务报表分析、工资核算、库存管理等...

Excel(WPS表格)Tocol函数应用技巧案例解读,建议收藏备用!

工作中,经常需要从多个单元格区域中提取唯一值,如体育赛事报名信息中提取唯一的参赛者信息等,此时如果复制粘贴然后去重,效率就会很低。如果能合理利用Tocol函数,将会极大地提高工作效率。一、功能及语法结...

Excel中的SCAN函数公式,把计算过程理清,你就会了

Excel新版本里面,除了出现非常好用的xlookup,Filter公式之外,还更新一批自定义函数,可以像写代码一样写公式其中SCAN函数公式,也非常强大,它是一个循环函数,今天来了解这个函数公式的计...

Excel(WPS表格)中多列去重就用Tocol+Unique组合函数,简单高效

在数据的分析和处理中,“去重”一直是绕不开的话题,如果单列去重,可以使用Unique函数完成,如果多列去重,如下图:从数据信息中可以看到,每位参赛者参加了多项运动,如果想知道去重后的参赛者有多少人,该...

Excel(WPS表格)函数Groupby,聚合统计,快速提高效率!

在前期的内容中,我们讲了很多的统计函数,如Sum系列、Average系列、Count系列、Rank系列等等……但如果用一个函数实现类似数据透视表的功能,就必须用Groupby函数,按指定字段进行聚合汇...

Excel新版本,IFS函数公式,太强大了!

我们举一个工作实例,现在需要计算业务员的奖励数据,右边是公司的奖励标准:在新版本的函数公式出来之前,我们需要使用IF函数公式来解决1、IF函数公式IF函数公式由三个参数组成,IF(判断条件,对的时候返...

Excel不用函数公式数据透视表,1秒完成多列项目汇总统计

如何将这里的多组数据进行汇总统计?每组数据当中一列是不同菜品,另一列就是该菜品的销售数量。如何进行汇总统计得到所有的菜品销售数量的求和、技术、平均、最大、最小值等数据?不用函数公式和数据透视表,一秒就...