sql隐式转换

This article will provide an overview of SQL Server implicit conversion including data type precedence and conversion tables, implicit conversion examples and means to detect occurrences of implicit conversion

本文将概述SQL Server隐式转换,包括数据类型优先级和转换表,隐式转换示例以及检测隐式转换发生的方法

SQL Server query performance issues are one of the most challenging processes for database administrators. In some cases, query performance can cause huge problems and it might affect the whole SQL Server instance performance. That is why every database administrator has some knowledge about query performance and troubleshooting methodologies.

SQL Server查询性能问题是数据库管理员面临的最具挑战性的过程之一。 在某些情况下,查询性能可能会导致巨大的问题,并且可能会影响整个SQL Server实例的性能。 这就是为什么每个数据库管理员都具有有关查询性能和故障排除方法的一些知识的原因。

Certainly, there are lots of factors and reasons which affect the query performance. However, the main principle or technique to solve these types of problems is based on well understanding and interpreting of the SQL execution plan of query. The SQL Execution plans show us series of steps which are taken during query execution, so we can uncover and find out any performance problems related to query. After all this brief information about query performance issues, we will discuss and learn the details of this kind of topic which affects query performance which is named as implicit conversion.

当然,有很多因素和原因会影响查询性能。 但是,解决这类问题的主要原理或技术是基于对查询SQL执行计划的充分理解和解释。 SQL执行计划向我们展示了在查询执行过程中采取的一系列步骤,因此我们可以发现并发现与查询相关的任何性能问题。 在获得了有关查询性能问题的所有简短信息之后,我们将讨论并学习这种影响查询性能的主题的详细信息,该主题称为隐式转换。

In some cases, we can combine two different data types in a join condition or we can compare two different data types in the where clause. In these cases, SQL Server tries to convert one data type to another during the query execution process. This data conversion process is referred to as Implicit Conversion because this type of conversion is made in behind of scenes by the SQL Server Query Optimizer and, as such, the process is abstracted from users. However, we can notice this type of conversion in the execution plan of the query.

在某些情况下,我们可以在联接条件中组合两种不同的数据类型,也可以在where子句中比较两种不同的数据类型。 在这些情况下,SQL Server会在查询执行过程中尝试将一种数据类型转换为另一种数据类型。 此数据转换过程称为“隐式转换”,因为这种类型的转换是由SQL Server查询优化器在后台进行的,因此,该过程是从用户中抽象出来的。 但是,我们可以在查询的执行计划中注意到这种类型的转换。

数据类型优先 (Data type precedence)

Before we start discussing implicit conversion, we will review the concept of data type precedence in SQL Server. As we have already noted, the miss-matched data types have to be converted to compatible formats by SQL Server and this data type conversion is also done according to a defined process governed by precedence. The data type precedence rule specifies which data type is converted to the other. The data types have precedence order for SQL Server and the lower precedence data type is converted to the higher precedence data type.

在开始讨论隐式转换之前,我们将回顾SQL Server中数据类型优先级的概念。 正如我们已经提到的,必须由SQL Server将未匹配的数据类型转换为兼容格式,并且此数据类型转换也要根据由优先级控制的已定义过程进行。 数据类型优先规则指定将哪种数据类型转换为另一种数据类型。 数据类型具有SQL Server的优先级顺序,较低优先级的数据类型将转换为较高优先级的数据类型。

  1. highest) 最高
  2. sql_variant sql_variant
  3. xml XML文件
  4. datetimeoffset 日期时间偏移
  5. datetime2 datetime2
  6. datetime 约会时间
  7. smalldatetime 小日期时间
  8. date 日期
  9. time 时间
  10. float 浮动
  11. real 真实
  12. decimal 小数
  13. money 钱
  14. smallmoney 小钱
  15. bigint 比金特
  16. int 整型
  17. smallint Smallint
  18. tinyint tinyint
  19. bit 一点
  20. ntext 文字
  21. text 文本
  22. image 图片
  23. timestamp 时间戳记
  24. uniqueidentifier 唯一标识符
  25. nvarchar (including nvarchar(max) ) nvarchar(包括nvarchar(max))
  26. nchar nchar
  27. varchar (including varchar(max) ) varchar(包括varchar(max))
  28. char 烧焦
  29. varbinary (including varbinary(max) ) varbinary(包括varbinary(max))
  30. lowest) 最低

例子 (Examples)

In the following query, we will compare two columns which have different datatypes so we will prove the methodology of precedence data type conversion rule.

在下面的查询中,我们将比较两个具有不同数据类型的列,以便证明优先数据类型转换规则的方法。

In the first step, we will create a single column table and this column data type is integer and we will populate some data to this table.

第一步,我们将创建一个单列表,并且此列的数据类型为整数,并将一些数据填充到该表中。

DROP TABLE IF EXISTS TestPreCREATE TABLE TestPre
(NumericCol INT)INSERT INTO TestPre
VALUES (1), (2), (3)

Now, we will execute the following query and interpret the execution plan of this query and also don’t forget to activate actual execution plan before executing the query.

现在,我们将执行以下查询并解释该查询的执行计划,并且不要忘记在执行查询之前激活实际的执行计划。

  SELECT * FROM TestPre WHERE NumericCol =N'1'

As you can see the above image, the query optimizer converts the textual data type to an integer because INT data type precedence is higher than NVARCHAR.

如上图所示,由于INT数据类型的优先级高于NVARCHAR,因此查询优化器将文本数据类型转换为整数。

数据类型转换 (Data type conversion)

The following summary conversion chart shows that which data type can be implicitly converted to another one.

下面的摘要转换表显示可以将哪种数据类型隐式转换为另一种数据类型。

转换限制 (Conversion limitations)

However, according to this chart, all possible data conversions cannot be made by SQL Server such. When we look at the following sample, SQL Server does not convert textual data types to integers. The output of this query will be an error.

但是,根据此图表,SQL Server无法进行所有可能的数据转换。 当我们看下面的示例时,SQL Server不会将文本数据类型转换为整数。 该查询的输出将是错误。

  SELECT * FROM TestPre WHERE NumericCol =N'A'

In addition, if you require this type of conversion, you can use TRY_PARSE or TRY_CONVERT functions so that you can overcome this type of errors during the query execution.

另外,如果您需要这种类型的转换,则可以使用TRY_PARSE或TRY_CONVERT函数,以便可以在查询执行期间克服此类错误。

Note: You can find all details in the Ben Richardson’s Understanding SQL Server’s TRY_PARSE and TRY_CONVERT functions article.

注意:您可以在Ben Richardson的《 了解SQL Server的TRY_PARSE和TRY_CONVERT函数》 文章中 找到所有详细信息

检测隐式转换 (Detecting implicit conversions )

Now, we will explore how to interpret execution plans which include implicit conversion. We will execute the following query in the Wide World Importers sample database and examine the actual execution plan.

现在,我们将探讨如何解释包含隐式转换的执行计划。 我们将在Wide World Importers示例数据库中执行以下查询,并检查实际的执行计划。

SELECT TransactionDate,IsFinalizedFROM [Sales].[CustomerTransactions]
where IsFinalized LIKE '1%'

As you can see in the above image, there is a warning sign in the select operator and it indicates that there is a problem in the execution plan. When we hover over the mouse icon in the Select operator, the detail screen will appear and we can find out the select operator details. The warning details clearly tell us the reason of the warning sign is implicit conversion. If we examine the detail of the execution plan, a wild card operator (%) is used for bit column and that is a problem because a bit column only takes two values and these are 1 (true) or 0 (false) so it does not make any sense to use ‘1%’ expression for bit column. When we go through the execution plan details, it makes the following conversion and this conversion purpose is convert textual data to bit data for this reason it takes the first character of the textual data.

如上图所示,select运算符中有一个警告标志,它指示执行计划中存在问题。 当我们将鼠标悬停在“选择”运算符中的鼠标图标上时,将显示详细信息屏幕,我们可以找到“选择”运算符的详细信息。 警告详细信息清楚地告诉我们警告标志是隐式转换的原因。 如果我们检查执行计划的详细信息,则通配符运算符(%)用于位列,这是一个问题,因为位列仅包含两个值,并且它们是1(true)或0(false),所以它确实对于位列使用' 1% '表达式没有任何意义。 当我们仔细查看执行计划的详细信息时,它将进行以下转换,并且此转换目的是将文本数据转换为位数据,因此它采用了文本数据的第一个字符。

CONVERT_IMPLICIT(varchar(1),[WideWorldImporters].[Sales].[CustomerTransactions].[IsFinalized],0)>='1'

In addition, we are seeing another detail in the select operator which is about “CardinalityEstimate”. The task of Cardinality Estimator is to determine how many rows will be returned from the query and so this estimation directly affects the ability to choose the proper index. However, in this query, incorrect data type conversion directly affects the used index in the query.

另外,我们在select运算符中看到了另一个有关“ CardinalityEstimate”的细节。 基数估计器的任务是确定将从查询返回多少行,因此该估计直接影响选择适当索引的能力。 但是,在此查询中,错误的数据类型转换将直接影响查询中使用的索引。

Let’s avoid the implicit conversion for this query. The solution is very basic because we will only convert the “IsFinalized LIKE ‘1%’’” expression to “IsFinalized = 1” so that the query will return the same result set and we will avoid the implicit conversion affects in the query.

让我们避免此查询的隐式转换。 该解决方案非常基础,因为我们将仅将“ IsFinalized LIKE'1%””表达式转换为“ IsFinalized = 1”,以便查询将返回相同的结果集,并避免查询中的隐式转换影响。

SELECT TransactionDate,IsFinalizedFROM [Sales].[CustomerTransactions]
where IsFinalized = 1

As you can see in the above image, there isn’t any warning sign in the execution plan and also the index scan operator has changed the index seek operator. This index seek operator directly improves the query performance because the index seek operator is more selective than the index scan operator. At this point I want to add a notice about some details about implicit conversion. The conversion processes don’t change the query plan so they don’t affect query performance. Therefore, these type of data conversions are considered acceptable processes, in the context of managing performance.

如上图所示,执行计划中没有任何警告标志,并且索引扫描运算符已更改了索引查找运算符。 该索引查找运算符直接改善了查询性能,因为索引查找运算符比索引扫描运算符更具选择性。 在这一点上,我想添加一个有关隐式转换的详细信息。 转换过程不会更改查询计划,因此不会影响查询性能。 因此,在管理性能方面,这些类型的数据转换被认为是可接受的过程。

In addition, we can detect implicit conversion issues in our database by the help of Extended Events. The plan_affecting_convert event captures queries whose data type conversion does affect the query execution plan. Now, we will create a new extended event through the following script.

此外,借助扩展事件,我们可以检测数据库中的隐式转换问题。 plan_affecting_convert事件捕获其数据类型转换确实会影响查询执行计划的查询。 现在,我们将通过以下脚本创建一个新的扩展事件。

CREATE EVENT SESSION [ImplicitConversionCapture] ON SERVER
ADD EVENT sqlserver.plan_affecting_convert(ACTION(sqlserver.database_name)WHERE ([sqlserver].[database_name]=N'WideWorldImporters')),
ADD EVENT sqlserver.sql_batch_completed(ACTION(sqlserver.database_name)WHERE ([sqlserver].[database_name]=N'WideWorldImporters')),
ADD EVENT sqlserver.sql_batch_starting(ACTION(sqlserver.database_name)WHERE ([sqlserver].[database_name]=N'WideWorldImporters'))
ADD TARGET package0.event_file(SET filename=N'ImplicitConversion')
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30
SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=OFF,STARTUP_STATE=OFF)
GO

We will start the extended event.

我们将开始扩展活动。

ALTER EVENT SESSION [ImplicitConversionCapture]  ON SERVER STATE= START

In this step, we will re-execute the following query which causes implicit conversion and then analyze the data which is captured by our extended event.

在这一步中,我们将重新执行以下查询,这将导致隐式转换,然后分析扩展事件捕获的数据。

SELECT TransactionDate,IsFinalizedFROM [Sales].[CustomerTransactions]
where IsFinalized  LIKE '1%'

The above image shows that the plan_affecting_convert event occurred due to prior query which was executed.

上图显示plan_affecting_convert事件是由于执行了先前的查询而发生的。

Another option is DMVs (Dynamic Management Views) which is used to detect implicit conversion. Through the following query, we can detect the implicit conversion issued queries.

另一个选项是DMV(动态管理视图),用于检测隐式转换。 通过以下查询,我们可以检测到隐式转换发出的查询。

SELECT  DB_NAME(sql_text.[dbid]) AS DatabaseName,
sql_text.text AS [Query Text],
query_stats.execution_count AS [Execution Count],
execution_plan.query_plan AS [Query Plan]
FROM sys.dm_exec_query_stats AS query_stats WITH (NOLOCK)
CROSS APPLY sys.dm_exec_sql_text(plan_handle) AS sql_text
CROSS APPLY sys.dm_exec_query_plan(plan_handle) AS execution_plan
WHERE
CAST(query_plan AS VARCHAR(MAX)) LIKE ('%CONVERT_IMPLICIT%')
AND
DB_NAME(sql_text.[dbid])='WideWorldImporters'
AND
CAST(query_plan AS VARCHAR(MAX)) NOT LIKE '%CROSS APPLY sys.dm_exec_sql_text(plan_handle) AS sql_text%'

结论 (Conclusion)

In this article, we discussed implicit conversion details, related performance implications and also about how to detect related issues with help of extended events and dynamic management views.

在本文中,我们讨论了隐式转换的详细信息,相关的性能含义以及有关如何借助扩展事件和动态管理视图检测相关问题的信息。

翻译自: https://www.sqlshack.com/implicit-conversion-in-sql-server/

sql隐式转换

sql隐式转换_SQL Server中的隐式转换相关推荐

  1. sql 触发器嵌套条件_SQL Server中的嵌套触发器

    sql 触发器嵌套条件 Nested Triggers in SQL Server are actions that automatically execute when a certain data ...

  2. 第3周 区_SQL Server中管理空间的基本单位

    第3周 区_SQL Server中管理空间的基本单位 原文:第3周 区_SQL Server中管理空间的基本单位 哇哦,SQL Server性能调优培训已经进入第3周了!同时你已经对SQL Serve ...

  3. ssis 列转换_SSIS包中的行采样转换和百分比采样转换

    ssis 列转换 This article explores Row Sampling Transformations in SSIS and Percentage Sampling Transfor ...

  4. sql隐式连接和显示链接_SQL Server中的嵌套循环联接–批处理排序和隐式排序

    sql隐式连接和显示链接 In SQL Server, it`s not always required to fully understand the internal structure, esp ...

  5. java代码转置sql数据_SQL Server中的数据科学:数据分析和转换–使用SQL透视和转置

    java代码转置sql数据 In data science, understanding and preparing data is critical, such as the use of the ...

  6. sql分区表上创建索引_SQL Server中分区表和索引的选项

    sql分区表上创建索引 介绍 (Introduction) I work for a large, multinational financial institution. Like most com ...

  7. sql limit 子句_SQL Server中的FOR XML PATH子句

    sql limit 子句 As SQL professionals, we often have to deal with XML data in our databases. This articl ...

  8. sql 线性回归_SQL Server中的Microsoft线性回归

    sql 线性回归 In this article, we will be discussing Microsoft Linear Regression in SQL Server. This is t ...

  9. sql 如何设置行级锁_SQL Server中的行级安全性简介

    sql 如何设置行级锁 In this article, I'm going to discuss Row-Level Security in SQL Server. RLS or Row-Level ...

最新文章

  1. 训练Epoch, Batch, Iteration
  2. 用树莓派打造世界上最小的“iMac”
  3. MySQL索引原理及慢查询优化 美团
  4. java 线程 wait 一定要同步_Java 线程中调用wait为什么一定要在同步代码块中?
  5. IBM TS3200 Drive故障处理方案
  6. 【AI面试题】什么是数据不平衡,如何解决
  7. 怎么样做好手机网站的优化和推广呢?
  8. CodeProject - 在C#使用SHGetFileInfo获取(管理)文件或者文件夹图标(C#封装Win32函数的一个例子)...
  9. sql server从数据库导出导入教程
  10. 剑指 offer set 8 树的子结构
  11. java反射基础_Java反射基础 - havie的笔记 - 记笔记 - 私塾在线 - 只做精品视频课程服务...
  12. JSON Viewer丨Json格式查看器
  13. Linux 常用操作命令大全(最后更新时间:2022年1月)
  14. Android NDK不得不说的秘密
  15. 清除右键新建中多余菜单
  16. 读书笔记:《活出生命的意义》
  17. 超详细的ArcGIS生成格网知识汇总
  18. iOS apple 登录
  19. 查看google浏览器里的证书
  20. linux检查内存插槽,Linux查看内存大小和插槽

热门文章

  1. flex布局怎么设置子元素大小_48张小图带你领略Flex 布局之美
  2. WITH ROLLUP、WITH CUBE、GROUPING语句的应用
  3. php安装redis扩展'checking for igbinary includes... configure: error: Cannot find igbinary.h'解决方法...
  4. MySQL备份mydumper的原理【转】
  5. 链接ftp,把文件或图片上传到ftp指定的文件夹中
  6. 我用 CSS 告诉你,我每天是怎么度过的~
  7. durpal是否支持php7,drupal7 的安装方法
  8. 读取swagger配置文件里的内容
  9. 怎么windows升级?windows版本升级?
  10. 有多少是长大了以后才明白的道理?