Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >比较列存储索引与行索引

比较列存储索引与行索引

作者头像
用户1217611
发布于 2018-01-30 08:27:08
发布于 2018-01-30 08:27:08
1.7K00
代码可运行
举报
文章被收录于专栏:文渊之博文渊之博
运行总次数:0
代码可运行

原因:

    之前已经写过一篇关于列存储索引的简介https://cloud.tencent.com/developer/article/1032222,很粗糙但是基本阐明了列存储索引的好处。为了更好的理解列存储索引,接下来我们一起通过列存储索引与传统的行存储索引地对比2014中的列存储索引带来了哪些改善。由于已经很多介绍列存储,因此这里我仅就性能的改进进行重点说明。

测试场景

    我创建了5个测试,尽量保证测试环境避免来自外界的重负载进而影响到结果。测试结果基于两个独立的表,分别是:

  • FactTransaction_ColumnStore - 这个表仅有一个聚集列存储索引,由于列存储索引的限制,该表不再有其他索引。
  • FactTransaction_RowStore - 该表将包含一个聚集索引和一个非聚集列存储索引和一个非聚集行存储索引。

    首先我用脚本文件创建表和索引,然后用30m行数据填充到三个表中。由于所有的测试我都制定了最大并行度的hint ,因此可以指定内核数量来查询。

测试1-填充表

   为了更好地测试,一个表由列存储索引构成,而另一个表仅有行存储索引构成。填充数据来自于另一个表'FactTransaction'。

IO 和时间统计

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Table 'FactTransaction_ColumnStore'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'FactTransaction'. Scan count 1, logical reads 73462, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

  (30000000 row(s) affected)

SQL Server Execution Times:  CPU time = 98204 ms,  elapsed time = 109927 ms.

Table ' FactTransaction_RowStore '. Scan count 0, logical reads 98566047, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'FactTransaction'. Scan count 1, logical reads 73462, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 (30000000 row(s) affected)

SQL Server Execution Times:  CPU time = 111375 ms,  elapsed time = 129609 ms.
观察测试

表名

填充时间

逻辑读

FacTransaction_ColumnStore

1.49 mins

0

FacTransaction_RowStore

2.09 mins

98566047

测试2-比较搜索

   注意这里在行存储索引上我指定表的hint,迫使表通过索引查找。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-- Comparing Seek.... 
SET Statistics IO,TIME ON

Select CustomerFK
From [dbo].FactTransaction_RowStore WITH(FORCESEEK)
Where transactionSK = 4000000
OPTION (MAXDOP 1)

Select CustomerFK
From [dbo].FactTransaction_ColumnStore  
Where transactionSK = 4000000
OPTION (MAXDOP 1)

SET Statistics IO,TIME OFF

IO 和时间统计

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Table 'FactTransaction_RowStore'. Scan count 0, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:    CPU time = 0 ms,  elapsed time = 0 ms.

Table 'FactTransaction_ColumnStore'. Scan count 1, logical reads 714, physical reads 0, read-ahead reads 2510, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:    CPU time = 0 ms,  elapsed time = 83 ms.

执行计划

观察测试2

正如上图所示,行存储索引表的索引查找远比列存储索引表查询快的多。这主要归因于2014的sqlserver不支持聚集列存储索引的索引查找。执行计划对比图中一个是索引扫描导致更多的逻辑读,因此导致了性能的下降。

表名

索引类型

逻辑读

运行时间

FacTransaction_ColumnStore

Column

714

83 ms

FacTransaction_RowStore

Row

3

0 ms

Test 3 - Comparing SCAN

   注意这次我指定的hint都是索引扫描,当然列存储索引上优化器默认为索引扫描。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-- Comparing Scan.... 
SET Statistics IO,TIME ON

Select CustomerFK
From [dbo].FactTransaction_RowStore WITH(FORCESCAN)
Where transactionSK = 4000000
OPTION (MAXDOP 1)

Select CustomerFK
From [dbo].FactTransaction_ColumnStore WITH(FORCESCAN)
Where transactionSK = 4000000
OPTION (MAXDOP 1)

SET Statistics IO,TIME OFF

IO 和时间统计

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Table 'FactTransaction_RowStore'. Scan count 1, logical reads 12704, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:
  CPU time = 32 ms,  elapsed time = 22 ms.

Table 'FactTransaction_ColumnStore'. Scan count 1, logical reads 714, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:
  CPU time = 0 ms,  elapsed time = 2 ms. 

执行计划

观察测试3

   正如之前提到的,索引扫描列存储要比行存储快,俩个逻辑读和运行时间表明列存储索引在大表扫描上是更优的方式,因此更适合于数据仓库的表。

表名

索引类型

逻辑读

运行时间

FacTransaction_ColumnStore

Column

714

2 ms

FacTransaction_RowStore

Row

12704

22 ms

测试4-聚合查询

    测试行存储表使用基于聚集索引。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SET Statistics IO,TIME ON

Select CustomerFK,BrandFK, Count(*)
From [dbo].[FactTransaction_RowStore] WITH(INDEX=RowStore_FactTransaction)
Group by CustomerFK,BrandFK
OPTION (MAXDOP 4)

   测试行存储表,使用CustomerFK 和BrandFK的索引。(覆盖索引)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Select CustomerFK,BrandFK, Count(*)
From [dbo].[FactTransaction_RowStore] WITH(INDEX=RowStore_CustomerFK_BrandFK)
Group by CustomerFK,BrandFK
OPTION (MAXDOP 4)

    测试行存储索引使用CustomerFK 和BrandFK的列存储索引(覆盖索引)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Select CustomerFK,BrandFK, Count(*) From [dbo].[FactTransaction_RowStore] WITH(INDEX=ColumnStore_CustomerFK_BrandFK) Group by CustomerFK,BrandFK OPTION (MAXDOP 4)

Test on the columnstore table using the Clustered Index.

Select CustomerFK,BrandFK, Count(*)
From [dbo].[FactTransaction_ColumnStore]
Group by CustomerFK,BrandFK
OPTION (MAXDOP 4)

SET Statistics IO,TIME OFF
IO 和时间统计

    使用基于聚集索引查询行存储的表。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Table 'FactTransaction_RowStore'. Scan count 5, logical reads 45977, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
  Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:  CPU time = 9516 ms,  elapsed time = 2645 ms.

   使用行存储的非聚集索引测试行存储表。(覆盖索引)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Table 'FactTransaction_RowStore'. Scan count 5, logical reads 71204, physical reads 0, read-ahead reads 2160, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:  CPU time = 5343 ms,  elapsed time = 1833 ms.

   使用非聚集列存储索引测试行存储表。(覆盖索引)

代码语言:javascript
代码运行次数:0
运行
复制
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Table 'FactTransaction_RowStore'. Scan count 4, logical reads 785, physical reads 7, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:  CPU time = 141 ms,  elapsed time = 63 ms.

    使用聚集索引测试列存储表。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Table 'FactTransaction_ColumnStore'. Scan count 4, logical reads 723, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:  CPU time = 203 ms,  elapsed time = 118 ms.
执行计划
观察测试4

   这里才是列存储索引开始“闪耀”的地方。两个列存储索引的表查询要比传统的航索引在逻辑读和运行时间上性能好得多。

表名

索引使用

索引类型

逻辑读

运行时间

FacTransaction_ColumnStore

ClusteredColumnStore

Column

717

118

FacTransaction_RowStore

RowStore_FactTransaction

Row

45957

2645

FacTransaction_RowStore

RowStore_CustomerFK_BrandFK

Row

71220

1833

FacTransaction_RowStore

ColumnStore_CustomerFK_BrandFK

Column

782

63

测试5-比较更新(数据子集)

   这个测试中,我将更新少于100m行数据,占总数据的30分之一。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SET Statistics IO,TIME ON

Update [dbo].[FactTransaction_ColumnStore]
Set    TransactionAmount = 100
Where  CustomerFK = 112
OPTION (MAXDOP 1)

Update [dbo].[FactTransaction_RowStore]
Set    TransactionAmount = 100
Where  CustomerFK = 112

OPTION (MAXDOP 1)

SET Statistics IO,TIME OFF
IO 和时间统计
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Table 'FactTransaction_ColumnStore'. Scan count 2, logical reads 2020, physical reads 0, read-ahead reads 2598, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(913712 row(s) affected)

SQL Server Execution Times:  CPU time = 27688 ms,  elapsed time = 37638 ms.

Table 'FactTransaction_RowStore'. Scan count 1, logical reads 2800296, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(913712 row(s) affected)

SQL Server Execution Times:  CPU time = 6812 ms,  elapsed time = 6819 ms.
执行计划
观察测试5

  在这种情况下 ,列存储索引的表要比行存储的更新慢的多。

表名

索引类型

逻辑读

运行时间

FacTransaction_ColumnStore

Column

2020

37638 ms

FacTransaction_RowStore

Row

2800296

6819 ms

    注意对于行存储表逻辑读还是要比行存储的要多很多。这是归因于列存储索引的压缩比率更高,因此占用更少的内存。

总结

    列存储索引(包含聚集和非聚集)提供了大量的优势。但是在数据仓库上使用还是要做好准备工作。一种合适地使用情况是非聚集索引不能被更新且禁用对底层表的更新。如果是巨大且没有分区的表,可能存在一个问题,整个表的索引每次都会被重建,因此如果表是巨大的则禁止使用列存储索引。因此必须要有好的分区策略来支持这种索引。

   有几个应用列存储索引的地方:事实表的聚合、Fast Track Data Warehouse Servers、恰当环境SSAS的Cube…

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-07-18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
⏱⏱动态SQL略知一二??
在使用 EF或者写 SQL语句时,查询条件往往是这样一种非常常见的逻辑:如果客户填了查询信息,则查询该条件;如果客户没填,则返回所有数据。
架构师修行之路
2020/02/11
6610
包含列的索引:SQL Server索引进阶 Level 5
作者David Durant,2011/07/13 关于系列 本文属于Stairway系列:Stairway to SQL Server Indexes 索引是数据库设计的基础,并告诉开发人员使用数据库关于设计者的意图。 不幸的是,当性能问题出现时,索引往往被添加为事后考虑。 这里最后是一个简单的系列文章,应该使他们快速地使任何数据库专业人员“快速”。 ---- 前面的级别引入了聚簇和非聚簇索引,突出了以下各个方面: 表中每一行的索引总是有一个条目(我们注意到这个规则的一个例外将在后面的级别中进行讨论)。
Woodson
2018/07/19
2.6K0
SQL Server索引简介:SQL Server索引进阶 Level 1
作者:David Durant,2014/11/05(首次发布:2011/02/17) 关于系列 本文属于进阶系列的:Stairway to SQL Server Indexes 索引是数据库设计的基础,并告诉开发人员使用数据库大量关于设计人员的意图。不幸的是,当性能问题出现时,索引通常被添加为事后的想法。最后这一系列简单的文章,应该能使任何数据库专业人员快速的“加快速度”。 ---- 此第一级引入SQL Server索引:数据库对象,使SQL Server能够在最短时间内查找和/或修改所请求的数据,使用最
Woodson
2018/07/18
1.6K0
sql sever 索引
微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引、簇集索引)和非聚集索引(nonclustered index,也称非聚类索引、非簇集索引)
week
2018/08/27
4880
列存储索引1:初识列存储索引
     2012以后提供了一种不同于传统B树结构的索引类型,就是内存列存储索引。这种索引应用了一种基于列的存储模式,也是一种新的查询执行的批处理模式,并且为特定的负载提供了巨大的性能提升。它是如何构建?如何工作?又是为什么能对性能有如此大的提升,接下来我们用简明的描述和详尽的示例来解释说明。      那么列存储索引究竟是什么?大多数时候,列存储索引被描述作为一种数据仓库和数据报表的功能。事实上,你最有可能就是在这种情况下利用这种索引。然而,即使在OLTP数据库中,你也会遇到一些要从大量数据表中获取数据的
用户1217611
2018/01/30
1.6K0
列存储索引1:初识列存储索引
深入非聚集索引:SQL Server索引进阶 Level 2
作者David Durant,2017/10/18(首次发布于:2014/11/26) 关于系列 本文属于进阶系列:Stairway to SQL Server Indexes 索引是数据库设计的基础,并告诉开发人员使用数据库关于设计者的意图。 不幸的是,当性能问题出现时,索引往往被添加为事后考虑。 这里最后是一个简单的系列文章,应该使他们快速地使任何数据库专业人员“快速” SQL Server索引阶段1中的级别1通常引入了SQL Server索引,特别引入了非聚簇索引。作为我们的第一个案例研究,我们演示了
Woodson
2018/07/19
1.6K0
SQL索引一步到位
SQL索引在数据库优化中占有一个非常大的比例, 一个好的索引的设计,可以让你的效率提高几十甚至几百倍,在这里将带你一步步揭开他的神秘面纱。   1.1 什么是索引?   SQL索引有两种,聚集索引和非聚集索引,索引主要目的是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间 下面举两个简单的例子: 图书馆的例子:一个图书馆那么多书,怎么管理呢?建立一个字母开头的目录,例如:a开头的书,在第一排,b开头的在第二排,这样在找什么书就好说了,这个就是一个聚集索引,可是很多人借书找某某作
Java高级架构
2018/07/20
1.6K0
v$sysstat表解释
按照OracleDocument中的描述,v$sysstat存储自数据库实例运行那刻起就开始累计全实例(instance-wide)的资源使用情况。
jack.yang
2025/04/05
730
聚集索引:SQL Server 进阶 Level 3
作者:David Durant,2013/01/25(首次发布于:2011/06/22) 关于系列 本文是属于Stairway系列:Stairway to SQL Server Indexes 索引是数据库设计的基础,并告诉开发人员使用数据库关于设计者的意图。不幸的是,当性能问题出现时,索引往往被添加为事后考虑。这里最后是一个简单的系列文章,应该使他们快速地使任何数据库专业人员“快速” 这个阶段的前面的层次提供了一般索引和非聚集索引的概述。它以下面关于SQL Server索引的关键概念结束。当请求到达您的数
Woodson
2018/07/19
1.2K0
[Oracle]-[SORT AGGREGATE]-count与索引
Oracle10g: create table t_count as select * from dba_objects; create index t_count_i on t_count(object_id): 分别用: select count(*) from t_count; select count(object_id) from t_count; select count(object_name) from t_count; 查看是否使用索引对count查询性能起到作用。 它们的执行计划: SQL> select count(*) from t_count; Execution Plan ---------------------------------------------------------- Plan hash value: 2197880521 ---------------------------------------------------------------------- | Id  | Operation           | Name    | Rows  | Cost (%CPU)| Time     | ---------------------------------------------------------------------- |   0 | SELECT STATEMENT   |             |           1 |          39   (0)| 00:00:01 | |   1 |  SORT AGGREGATE    |             |           1 |                  |             | |   2 |   TABLE ACCESS FULL| T_COUNT | 12028 |          39   (0)| 00:00:01 | ---------------------------------------------------------------------- Note -----    - dynamic sampling used for this statement SQL> select count(object_name) from t_count;
bisal
2019/01/29
8950
SQL Server 深入解析索引存储(下)
概述 非聚集索引与聚集索引具有相同的 B 树结构,它们之间的显著差别在于以下两点: 基础表的数据行不按非聚集键的顺序排序和存储。 非聚集索引的叶层是由索引页而不是由数据页组成。 既可以使用聚集索引来为表或视图定义非聚集索引,也可以根据堆来定义非聚集索引。非聚集索引中的每个索引行都包含非聚集键值和行定位符。此定位符指向聚集索引或堆中包含该键值的数据行。 非聚集索引行中的行定位器或是指向行的指针,或是行的聚集索引键,如下所述: 如果表是堆(意味着该表没有聚集索引),则行定位器是指向行的指针。该指针由文件标
逸鹏
2018/04/11
9370
SQL Server 深入解析索引存储(下)
SQL Server 2014聚集列存储索引
 转发请注明引用和原文博客(https://cloud.tencent.com/developer/user/1217611/activities) 简介   之前已经写过两篇介绍列存储索引的文章,但是只有非聚集列存储索引,今天再来简单介绍一下聚集的列存储索引,也就是可更新列存储索引。在SQL Server 2012中首次引入了基于列存储数据格式的存储方式。叫做“列存储索引”。前一篇我已经比较了行存储索引与非聚集的列存储索引(https://cloud.tencent.com/developer/artic
用户1217611
2018/01/30
1.1K0
SQL Server 2014聚集列存储索引
SQL Server 2014聚集列存储索引
  之前已经写过两篇介绍列存储索引的文章,但是只有非聚集列存储索引,今天再来简单介绍一下聚集的列存储索引,也就是可更新列存储索引。在SQL Server 2012中首次引入了基于列存储数据格式的存储方式。叫做“列存储索引”。前一篇我已经比较了行存储索引与非聚集的列存储索引(http://www.cnblogs.com/wenBlog/p/5682024.html)。其中对于在小表的指定值或者小范围的查询来讲,尤其针对事务性的负载行存储是很合适的。但是对于分析性负载像数据仓库和BI,在查询中将会对大量数据进行全扫描,例如事实表,这时候列存储索引就是更好地选择。
用户1217611
2018/09/28
1.1K0
SQL Server 2014聚集列存储索引
SqlServer 资源消耗查询
SqlServer 的“读写查”占了整个程序的60%,特别是效能这块,在小数据还好,如果去到大数据那就麻烦了,以前做过一个测试就是批量复制和单条复制的效率问题,感兴趣的同学可以查查我以前写的文档,今天就说说如何查询SqlServer的资源消耗情况,这样就能对应问题的根本。。。
谭广健
2020/08/11
2.1K0
《T-SQL查询》读书笔记Part 3.索引的基本知识
索引优化是查询优化中最重要的一部分,索引是一种用于排序和搜索的结构,在查找数据时索引可以减少对I/O的需要;当计划中的某些元素需要或是可以利用经过排序的数据时,也会减少对排序的需要。某些方面的优化可以适度提高性能,而索引优化经常可以大幅度地提高查询性能。
Edison Zhou
2018/08/21
7530
《T-SQL查询》读书笔记Part 3.索引的基本知识
一个用 Oracle 函数索引进行优化的例子
该文介绍了如何使用Oracle函数索引优化查询性能。通过一个例子,展示了在查询中添加函数索引后,查询速度大大提高。同时还介绍了如何使用索引进行排序,以及如何使用analyze命令来查看统计信息。
用户1148526
2018/01/03
1.8K0
SQLSERVER数据库死锁与优化杂谈
当数据库死锁时,SqlServer会释放一个优先级较低的锁,让另一个事务运行;所以,即时去捕捉数据库死锁,是挺不容易的。
Kiba518
2019/03/05
2.2K0
程序猿是如何解决SQLServer占CPU100%的
文章目录 遇到的问题 使用SQLServer Profiler监控数据库 SQL1:查找最新的30条告警事件 SQL2:获取当前的总报警记录数 有哪些SQL语句会导致CPU过高? 查看SQL的查询计划
逸鹏
2018/04/11
1.6K0
程序猿是如何解决SQLServer占CPU100%的
【DB笔试面试622】在Oracle中,说说COUNT(*)计算行数有哪些优化手段?
位图索引可以按很高密度存储数据,因此往往比B树索引小很多,前提是在基数比较小(列重复度比较高)的情况下。位图索引是保存空值的,因此可以在COUNT中利用。位图索引不太适合OLTP类型数据库。物化视图是应用在数据要求不怎么及时的场景下。若表频繁更新,则不适合缓存结果集。
AiDBA宝典
2019/09/29
9810
INDEX FULL SCAN vs INDEX FAST FULL SCAN
     INDEX FULL SCAN 与 INDEX FAST FULL SCAN两个长相差不多,乃是一母同胞,因此既有其共性,也有其个性。两者来说其共性是不用扫描表而是通过索引就可以直接返回所需要的所有数据。这对提高查询性能而言,无疑是一个难得的数据访问方式之一,因为索引中存储的数据通常是远小于原始表的数据。下面具体来看看两者之间的异同。
Leshami
2018/08/14
2.5K0
相关推荐
⏱⏱动态SQL略知一二??
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验