SQL Server-聚焦UNIOL ALL/UNION查询

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS SQL Server,基础系列 2核4GB
简介:

初探UNION和UNION ALL

首先我们过一遍二者的基本概念和使用方法,UNION和UNION ALL是将两个表或者多个表进行JOIN,当然表的数据类型必须相同,对于UNION而言它会去除重复值,而UNION ALL则会返回所有数据,这就是二者的区别和使用方法。下面我们来看一个简单的例子。

USE TSQL2012
GO--USE UNION ALL
SELECT 1
    UNION ALL 
SELECT 2
    UNION ALL
SELECT 2
    UNION ALL
SELECT 3--USE UNION
SELECT 1
    UNION
SELECT 2
    UNION
SELECT 2
    UNION
SELECT 3

上述我们稍微讲解了下二者的基本使用,接下来我们来看看二者的性能比较。

进一步探讨UNION 和 UNION ALL性能问题

我们首先创建两个测试表Table1和Table2

USE TSQL2012
GO

CREATE TABLE Table1
(
    col VARCHAR(10)
)

CREATE TABLE Table2
(
    col VARCHAR(10)
)

在表Table1中插入如下测试数据

USE TSQL2012
GO

INSERT INTO Table1
SELECT 'First'UNION ALL
SELECT 'Second'UNION ALL
SELECT 'Third'UNION ALL
SELECT 'Fourth'UNION ALL
SELECT 'Fifth'

在表Table2中插入如下测试数据

USE TSQL2012
GO

INSERT INTO Table2
SELECT 'First'UNION ALL
SELECT 'Third'UNION ALL
SELECT 'Fifth'

我们查询下两个表插入的测试数据

USE TSQL2012
GO

SELECT *FROM Table1

SELECT *FROM Table2

接着分别利用UNION和UNION ALL来查询数据比较二者性能开销

USE TSQL2012
GO--UNION ALL
SELECT *FROM Table1
UNION ALL
SELECT *FROM Table2--UNION
SELECT *FROM Table1
UNION
SELECT *FROM Table2

 

此时我们能够很明显的看到因为UNION要去除重复所以会进行DISTINCT Sort操作使得其性能要低于UNION ALL。到这里我们可以下个基本结论。

UNION VS UNION ALL性能分析结论:当使用UNION查询语句时类似会进行SELECT DISTINCT操作,除非我们非常明确要返回唯一不重复的值那就用UNION,否则使用UNION ALL会带来更好的性能,返回结果集更快。

是不是到此就完了呢,使用UNION和UNION ALL就这么简单么,那你就太天真了,我们继续往下看。

深入探讨UNION 和 UNION ALL(一)

我们声明一个表变量插入数据并利用UNION ALL来进行查询

USE TSQL2012
GO

DECLARE @tempTable TABLE(col TEXT)
INSERT INTO @tempTable(col)
SELECT 'JeffckyWang'SELECT col FROM @tempTableUNION ALL SELECT 'Test UNION ALL'

此时对应返回合并结果集,恩,没毛病,我们接下来看看UNION

USE TSQL2012
GO

DECLARE @tempTable TABLE(col TEXT)
INSERT INTO @tempTable(col)
SELECT 'JeffckyWang'SELECT col FROM @tempTableUNION SELECT 'Test UNION ALL'

此时毛病就出来了,说什么数据类型text不可比,不能将其用作UNIN、INTERSERCT或EXCEPT等运算符的操作数,这是什么意思,不太懂。在我们讲解UNION和UNION ALL的性能问题时,我们已经标出UNION的查询计划,UNION会进行DISTINCT Sort操作,这说明什么呢?实际上它内部会进行自动排序同时移除重复的数据,此时数据类型为TEXT所以无法对TEXT类型进行排序,换句话说UNION不支持TEXT类型。所以到这里我们可以给出一个结论。

当利用UNION进行查询时,如果查询列中有TEXT数据类型时,此时会发生错误,因为UNION内部会自动对数据进行排序,而TEXT是无法进行排序的,所以UNION不支持TEXT数据类型。

好了到了这里,我们才算是给出第一个需要注意的地方,下面我们再来看一个。

深入探讨UNION和UNION ALL(二)

当我们对两个表进行UNION ALL时,此时我们如果有这样一个需求,需要使用UNION ALL前后的表是进行排序的,那么此时我们应该如何做呢?下面我们创建测试表看看。

USE TSQL2012
GO

CREATE TABLE Table1 (ID INT, Col1 VARCHAR(100));
CREATE TABLE Table2 (ID INT, Col1 VARCHAR(100));
GO

INSERT INTO Table1 (ID, Col1)
SELECT 1, 'Col1-t1'UNION ALL
SELECT 2, 'Col2-t1'UNION ALL
SELECT 3, 'Col3-t1';

INSERT INTO Table2 (ID, Col1)
SELECT 3, 'Col1-t2'UNION ALL
SELECT 2, 'Col2-t2'UNION ALL
SELECT 1, 'Col3-t2';
GO

此时我们查询上述Table1和Table2数据如下:

我们的需求是利用UNION ALL将Table1和Table2合并时,其顺序分别是1,2,3和1,2,3。对于UNION查询我们就不用讨论,内部会自行排序,如下则是利用UNION对数据进行排序的结果:

当我们进行UNION ALL时呢

USE TSQL2012
GO

SELECT ID, Col1
FROM dbo.Table1
  UNION ALL
SELECT ID, Col1
FROM dbo.Table2
GO

显然满足不了我们的需求,在Table2表中的数据我们需要的是1,2,3。那么我们对Table2中的ID进行ORDER BY结果会如何呢?

USE TSQL2012
GO

SELECT ID, Col1
FROM dbo.Table1
    UNION ALL
SELECT ID, Col1
FROM dbo.Table2
ORDER BY ID
GO

使用UNION ALL通过对Table2表上的ID进行ORDER BY此时得到的结果和上述UNION查询的结果很类似,但是还是没有得到我们的结果。上述对于两个结果集进行合并后的排序也可以进行如下查询:

USE TSQL2012
GO

SELECT * FROM
(SELECT ID, Col1 FROM dbo.Table1
UNION ALL
SELECT ID, Col1 FROM dbo.Table2) as t
ORDER BY ID

对于查询我们能够自定义常量列,我们接下来添加一个额外的常量列,先对其常量列进行排序,然后对ID进行ORDER BY呢,结果又会是怎样的呢?

USE TSQL2012
GO

SELECT ID, Col1, 'addtionalcol1' AS addtionalCol FROM dbo.Table1
    UNION ALL
SELECT ID, Col1, 'addtionalCol2' AS addtionalColFROM dbo.Table2
ORDER BY addtionalCol, ID
GO

到这里算是基本完成我们的需求,貌似需要额外添加一个列,虽然效果不是太好。



本文转自 sshpp 51CTO博客,原文链接:http://blog.51cto.com/12902932/1926499,如需转载请自行联系原作者

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
相关文章
|
4天前
|
SQL 运维 程序员
一个功能丰富的SQL审核查询平台
一个功能丰富的SQL审核查询平台
|
11天前
|
SQL 数据库 Java
HQL vs SQL:谁将统治数据库查询的未来?揭秘Hibernate的神秘力量!
【8月更文挑战第31天】Hibernate查询语言(HQL)是一种面向对象的查询语言,它模仿了SQL的语法,但操作对象为持久化类及其属性,而非数据库表和列。HQL具有类型安全、易于维护等优点,支持面向对象的高级特性,内置大量函数,可灵活处理查询结果。下面通过示例对比HQL与SQL,展示HQL在实际应用中的优势。例如,HQL查询“从员工表中筛选年龄大于30岁的员工”只需简单地表示为 `FROM Employee e WHERE e.age > 30`,而在SQL中则需明确指定表名和列名。此外,HQL在处理关联查询时也更为直观易懂。然而,对于某些复杂的数据库操作,SQL仍有其独特优势。
21 0
|
11天前
|
SQL 关系型数据库 MySQL
|
11天前
|
API Java 数据库连接
从平凡到卓越:Hibernate Criteria API 让你的数据库查询瞬间高大上,彻底告别复杂SQL!
【8月更文挑战第31天】构建复杂查询是数据库应用开发中的常见需求。Hibernate 的 Criteria API 以其强大和灵活的特点,允许开发者以面向对象的方式构建查询逻辑,同时具备 SQL 的表达力。本文将介绍 Criteria API 的基本用法并通过示例展示其实际应用。此 API 通过 API 构建查询条件而非直接编写查询语句,提高了代码的可读性和安全性。无论是简单的条件过滤还是复杂的分页和连接查询,Criteria API 均能胜任,有助于提升开发效率和应用的健壮性。
19 0
|
11天前
|
Java UED 开发者
当错误遇上Struts 2:一场优雅的异常处理盛宴,如何让错误信息成为用户体验的救星?
【8月更文挑战第31天】在Web应用开发中,异常处理对确保用户体验和系统稳定性至关重要。Struts 2 提供了完善的异常处理机制,包括 `exception` 拦截器、`ActionSupport` 类以及 OGNL 表达式,帮助开发者优雅地捕获和展示错误信息。本文详细介绍了 Struts 2 的异常处理策略,涵盖拦截器配置、错误信息展示及自定义全局异常处理器的实现方法,使应用程序更加健壮和用户友好。
15 0
|
11天前
|
Java XML Maven
跨越时代的飞跃:Struts 2 升级秘籍——从旧版本无缝迁移到最新版,焕发应用新生!
【8月更文挑战第31天】随着软件技术的发展,Struts 2 框架也在不断更新。本文通过具体案例指导开发者如何从旧版平滑升级到 Struts 2.6.x。首先更新 `pom.xml` 中的依赖版本,并执行 `mvn clean install`。接着检查 `struts.xml` 配置,确保符合新版本要求,调整包扫描器等设置。审查 Action 类及其注解,检查配置文件中的弃用项及插件。更新自定义拦截器实现,并验证日志配置。最后,通过一系列测试确保升级后的系统正常运行。通过这些步骤,可以顺利完成 Struts 2 的版本升级,提升应用的安全性和性能。
36 0
|
11天前
|
前端开发 开发者
Vaadin Grid的秘密武器:打造超凡脱俗的数据展示体验!
【8月更文挑战第31天】赵萌是一位热爱UI设计的前端开发工程师。在公司内部项目中,她面临大量用户数据展示的挑战,并选择了功能强大的Vaadin Grid来解决。她在技术博客上分享了这一过程,介绍了Vaadin Grid的基本概念及其丰富的内置功能。通过自定义列和模板,赵萌展示了如何实现复杂的数据展示。
18 0
|
11天前
|
SQL 存储 安全
Play Framework的安全面纱:揭开隐藏在优雅代码下的威胁
【8月更文挑战第31天】Play Framework 是一款高效、轻量级的 Web 开发框架,内置多种安全特性,助力开发者构建安全稳定的应用。本文详细介绍 Play 如何防范 SQL 注入、XSS 攻击、CSRF 攻击,并提供安全的密码存储方法及权限管理策略,通过具体示例代码展示实施步骤,助您有效抵御常见威胁。
27 0
|
11天前
|
SQL 关系型数据库 MySQL
|
11天前
|
SQL 数据库