t-sql 使用正则表达式

挑战 (The challenge)

One of the main tasks of a SQL Server database administrator is performance tuning. Sometimes, though, coders or developers don’t always prioritize database performance or query optimization. Here is a typical scenario

SQL Server数据库管理员的主要任务之一是性能调整。 但是,有时,编码人员或开发人员并不一定总是优先考虑数据库性能或查询优化。 这是一个典型的场景

  • Imagine that developers create a new table and then insert some records in a test environment and test their queries to retrieve data from it 想象一下,开发人员创建一个新表,然后在测试环境中插入一些记录并测试他们的查询以从中检索数据
  • The query executed successfully and does not exhibit any symptoms of performance problems 查询成功执行,没有任何性能问题的征兆
  • The developer team release this table and query into production 开发人员团队发布此表并查询生产
  • One day you take a telephone from your colleague and he says my report is very slow 有一天,您从同事那里接电话,他说我的报告很慢
  • Bingo! In production, this table contains a lot of records and this is resulting in performance bottlenecks when querying it 答对了! 在生产中,此表包含很多记录,这在查询时会导致性能瓶颈

I think this scenario is all too common to many SQL Server DBAs.

我认为这种情况对于许多SQL Server DBA来说太普遍了。

In my opinion developers who work with SQL Server often have a little knowledge about query performance tuning. In this scenario, a little knowledge would have gone a long way to preventing these issues in production.

在我看来,使用SQL Server的开发人员通常对查询性能调整有一点了解。 在这种情况下,为防止这些问题在生产中使用一点知识将大有帮助。

可查询 (Sargable queries)

Sargable is a word that concatenates the three words: search, argument and able.

Sargable是一个将三个词连接在一起的词: search,arguments和能力

As per wikipedia SARGable is defined as “In relational databases, a condition (or predicate) in a query is said to be sargable if the DBMS engine can take advantage of an index to speed up the execution of the query. The term is derived from a contraction of Search ARGument ABLE”

按照维基百科可优化搜索被定义为“在关系数据库中,在一个查询中的条件(或谓词)被说成是可优化搜索如果DBMS引擎可以采取索引的优点,以加快查询的执行。 该术语源自Search ArGument ABLE的收缩”

Advantage of sargable queries include:

可查询的优点包括:

  • consuming less system resources 消耗更少的系统资源
  • speeding up query performance 加快查询性能
  • using indexes more effectively 更有效地使用索引

指标 (Indexes)

Now we will shortly discuss about index basics then we will cover some examples of both sargable and non-sargable queries.

现在我们将简短地讨论索引基础,然后我们将讨论可查询和不可查询的一些示例。

Indexes are created on tables or views. Indexes can be likened to a book directory and improve the speed of searches. Some examples of different types of indexes are clustered indexes, non-cluster indexes and columnstore indexes.

在表或视图上创建索引 。 索引可以比作书籍目录,并提高搜索速度。 不同类型的索引的一些示例是聚簇索引,非聚簇索引和列存储索引。

An index scan is when SQL Server reads all the data in the index pages. The cost of an index scan is very expensive for the SQL Server Engine.

索引扫描是指SQL Server读取索引页中的所有数据。 对于SQL Server引擎,索引扫描的成本非常昂贵。

An index seek is when SQL Server reads only matching data in the index pages. This method is more efficient for query performance because it will reduce IO and time consumption.

索引查找是指SQL Server仅读取索引页中的匹配数据。 这种方法对于查询性能更有效,因为它将减少IO和时间消耗。

例子 (Examples)

Now we will start examples. In our examples we will look at non-sargable queries and their execution plans. Then we will convert a non-sargable query to a sargable query. Finally, we will compare non-sargable and sargable queries time and IO statistics.

现在,我们将开始示例。 在我们的示例中,我们将研究不可持久查询及其执行计划。 然后,我们将不可查询的查询转换为可查询的查询。 最后,我们将比较不可保留和可保留的查询时间以及IO统计信息。

Now we will create our dummy table and insert records for queries

现在,我们将创建虚拟表并插入查询记录

DROP TABLE IF EXISTS Dummy_PersonTable
CREATE TABLE Dummy_PersonTable
(   ID [int] NOT NULL PRIMARY KEY IDENTITY(1,1),[PersonType] [nchar](2) NOT NULL,[NameStyle] [dbo].[NameStyle] NOT NULL,[Title] [nvarchar](8) NULL,[FirstName] [dbo].[Name] NOT NULL,[MiddleName] [dbo].[Name] NULL,[LastName] [dbo].[Name] NOT NULL,[Suffix] [nvarchar](10) NULL,[EmailPromotion] [int] NOT NULL,[AdditionalContactInfo] [xml](CONTENT [Person].[AdditionalContactInfoSchemaCollection]) NULL,[Demographics] [xml](CONTENT [Person].[IndividualSurveySchemaCollection]) NULL,[rowguid] [uniqueidentifier] ROWGUIDCOL  NOT NULL,[ModifiedDate] [datetime] NOT NULL )CREATE NONCLUSTERED INDEX [NonClustered_FirstName] ON [dbo].[Dummy_PersonTable]
([FirstName] ASC)
CREATE NONCLUSTERED INDEX [NonClustered_ModifiedDate] ON [dbo].[Dummy_PersonTable]
([ModifiedDate] ASC
)CREATE NONCLUSTERED INDEX [NonClustered_MiddleName] ON [dbo].[Dummy_PersonTable]
([MiddleName] ASC
)INSERT INTO Dummy_PersonTableSELECT [PersonType],[NameStyle],[Title],[FirstName],[MiddleName],[LastName],[Suffix],[EmailPromotion],[AdditionalContactInfo],[Demographics],[rowguid],[ModifiedDate]FROM [Person].[Person]GO 100

This dummy table includes a non-clustered index on the FirstName, ModifiedDate and MiddleName columns.

该虚拟表在FirstName,ModifiedDate和MiddleName列上包括一个非聚集索引。

在WHERE子句中使用函数 (Using functions in the WHERE clause)

In this first example, we will select records in the Person table which starts with the letter “K”.

在第一个示例中,我们将在“人”表中选择以字母“ K”开头的记录。

Non-sargable query:

不可查询:

SELECT FirstName  FROM Dummy_PersonTable where LEFT(FirstName,1)='K'

The SQL Server query optimizer cannot find the result of ths LEFT function values in the index pages. For this reason, the query optimizer chooses a cluster index scan and it needs to read the whole table.

SQL Server查询优化器无法在索引页中找到LEFT函数值的结果。 因此,查询优化器选择集群索引扫描,并且它需要读取整个表。

In the below picture, the Estimated Number of Rows to be Read value is 5,991,600. This value is the total row number of the table. But the matching records are approximately 371,400

在下图中,“预计要读取的行数”值为5,991,600。 该值是表的总行数。 但匹配的记录约为371,400

These functions create the same execution plans in the same conditions

这些功能在相同条件下创建相同的执行计划

  • SUBSTRING 订阅
  • LEFT 剩下
  • LTRIM LTRIM
  • RTRIM RTRIM
  • User defined functions 用户定义的功能

Sargable query:

可查询的查询:

Now we will make a little syntax change in the previous query

现在,我们将在上一个查询中进行一些语法更改

SELECT FirstName  FROM Dummy_PersonTable where FirstName  LIKE 'K%'

SQL Server query optimizer decides to use an index seek operator when the operator cost is low and it can easily find matching records using the B-Tree structure. An index seek operator provides significant performance gains.

SQL Server查询优化器决定在索引运算符成本较低并且可以使用B-Tree结构轻松找到匹配记录时决定使用索引查找运算符。 索引查找运算符可显着提高性能。

In the below picture, the Estimated Number of Rows to be Read value is equal to the Estimated Number of Rows because index seek operator directly achieves a matching result of the query

在下图中,因为索引查找运算符直接获得查询的匹配结果,所以“ 要读取的行数估计”值等于“行数估计”

Type Table Scan count Logical reads Physical reads
Non-sargable Dummy_PersonTable 5 19,392 0
Sargable Dummy_PersonTable 1 1,229 0
类型 扫描计数 逻辑读取 物理阅读
不可燃 假人表 5 19,392 0
可精 假人表 1个 1,229 0

This table show us IO statistics of these two queries. The sargable query performs significantly better than the Non-sargable query

该表向我们显示了这两个查询的IO统计信息。 可查询查询的性能明显优于不可查询查询

Type Table CPU Time(ms) Elapsed time(ms)
Non-sargable Dummy_PersonTable 1593 2145
Sargable Dummy_PersonTable 203 1830
类型 CPU时间(毫秒) 经过时间(毫秒)
不可燃 假人表 1593 2145
可精 假人表 203 1830年

This table shows us time statistics of queries and it can be seen that the sargable query demonstrates better performance than the Non-sargable query.

该表向我们显示了查询的时间统计信息,可以看出,可精简查询比不精简查询表现出更好的性能。

Tip: We will add a calculated column for the LEFT function and create a non-clustered index

提示:我们将为LEFT函数添加一个计算列,并创建一个非聚集索引

DROP INDEX IF EXISTS FirstName_Left ON Dummy_PersonTable
ALTER TABLE dbo.Dummy_PersonTable  ADD FirstName_Left   AS LEFT(FirstName,1)
CREATE NONCLUSTERED INDEX [NonClusteredIndex_LeftFirstName] ON [dbo].[Dummy_PersonTable]
([FirstName_Left] ASC
)
INCLUDE (   [FirstName])

Now we will look again at the non-sargable query execution plan.

现在,我们将再次查看不可保留的查询执行计划。

It will use an index seek

它将使用索引查找

This is an alternative solution for performance gain but changing T-SQL syntax is much easier than changing the table structure and adding an index.

这是提高性能的替代解决方案,但是更改T-SQL语法比更改表结构和添加索引要容易得多。

DateTime函数 (DateTime functions)

In this example, our target is to write a select query for a specific year. We can write this query as shown below.

在此示例中,我们的目标是编写特定年份的选择查询。 我们可以编写如下所示的查询。

Non-sargable query:

不可查询:

SELECT ModifiedDate FROM Dummy_PersonTable where YEAR(ModifiedDate)=2009

We will look at this query execution plan

我们将看一下这个查询执行计划

The SQL Server query optimizer cannot use an index seek because it cannot find the values of the YEAR function on the index pages.

SQL Server查询优化器无法使用索引查找,因为它无法在索引页上找到YEAR函数的值。

Tip: Maybe you can ask this question. Why does SQL Server query optimizer decide to use a parallel plan? The SQL Server query optimizer decides on a parallel plan because the optimizer works on a cost-based method and it decides that a parallel plan is cheaper than a serial plan. We will compare the parallel and serial execution plans Estimated subtree cost

提示:也许您可以问这个问题。 为什么SQL Server查询优化器决定使用并行计划? SQL Server查询优化器决定并行计划,因为该优化器使用基于成本的方法,并且确定并行计划比串行计划便宜。 我们将比较并行执行计划和串行执行计划

The parallel execution plan cost is 15.03 and the serial execution plan cost is 17.08. This is the main reason for this decision. There are other reasons to take this decision though:

并行执行计划成本为15.03,串行执行计划成本为17.08。 这是做出此决定的主要原因。 但是,还有其他原因可以做出此决定:

If

如果

  • SQL Server engine has more than one CPU SQL Server引擎具有多个CPU
  • The SQL Server maximum degree of parallelism (MAXDOP) setting is more than 1 SQL Server最大并行度(MAXDOP)设置大于1
  • The execution plan cost is greater than the cost threshold for parallelism setting value 执行计划成本大于并行度设置值的成本阈值

… then SQL Server query optimizer choice parallel plan.

…然后SQL Server查询优化器选择并行计划。

Sargable query:

可查询的查询:

In this step we will change the condition in this query.

在这一步中,我们将更改此查询中的条件。

SELECT ModifiedDate FROM Dummy_PersonTable where ModifiedDate BETWEEN '20090101' AND '20091231'

The SQL Server query optimizer performs an index seek. Now we will compare IO and time statistics

SQL Server查询优化器执行索引查找。 现在我们将比较IO和时间统计信息

Type Table Scan count Logical reads Physical reads
Non-sargable Dummy_PersonTable 5 13526 0
Sargable Dummy_PersonTable 1 185 0
类型 扫描计数 逻辑读取 物理阅读
不可燃 假人表 5 13526 0
可精 假人表 1个 185 0
Type Table CPU time(ms) Elapsed time(ms)
Non-sargable Dummy_PersonTable 1048 644
Sargable Dummy_PersonTable 0 340
类型 CPU时间(毫秒) 经过时间(毫秒)
不可燃 假人表 1048 644
可精 假人表 0 340

Our results demonstrate that the sargable query has out-performed the non-sargable query

我们的结果表明,可精简查询的性能优于不可精简查询

在WHERE子句上使用ISNULL函数 (Using ISNULL function on WHERE clause)

In this sample we want to select all of records where the MiddleName is equal to “E” or NULL. We can write the query like this. We will activate Include Client Statistics for comparing non-sargable and sargable queries.

在此示例中,我们希望选择MiddleName等于“ E”或NULL的所有记录。 我们可以这样编写查询。 我们将激活“包含客户端统计信息”,以比较不可查询和可查询。

Non-sargable query:

不可查询:

SELECT MiddleName FROM Dummy_PersonTable where ISNULL(MiddleName,'E') ='E'

Sargable query:

可查询的查询:

We will change syntax of query and use an index seek

我们将更改查询的语法并使用索引查找

SELECT MiddleName FROM Dummy_PersonTable where  (MiddleName IS NULL OR MiddleName='E')

As seen above, the non-sargable (Trial 1) query execution plan used an index scan and the sargable query (Trial 2) used an index seek. These differences the between two queries affected performance. This case clearly shown in the below client statistics chart.

如上所示,非可存储查询(试验1)使用索引扫描,而可存储查询(试验2)使用索引查找。 两个查询之间的这些差异影响了性能。 下面的客户统计信息图表清楚地显示了这种情况。

结论 (Conclusions)

In this article, we discussed sargable and non-sargable queries. Non-sargable queries can result in poor system performance. We can often improve these queries by changing the code, to leverage indexes and in doing so, convert them to sargable queries. Sargable queries can improve performance on CPU and IO as was demonstrated by our analysis and findings.

在本文中,我们讨论了可查询和不可查询。 不可持久查询可能会导致系统性能下降。 我们通常可以通过更改代码,利用索引并将其转换为可查询的查询来改进这些查询。 正如我们的分析和发现所表明的那样,可查询的查询可以提高CPU和IO的性能。

翻译自: https://www.sqlshack.com/how-to-use-sargable-expressions-in-t-sql-queries-performance-advantages-and-examples/

t-sql 使用正则表达式

t-sql 使用正则表达式_如何在T-SQL查询中使用可扩展表达式; 性能优势和实例相关推荐

  1. java js 正则表达式_如何在JavaScript与Java中使用正则表达式

    如何在JavaScript与Java中使用正则表达式 发布时间:2021-02-11 13:16:01 来源:亿速云 阅读:69 作者:Leah 如何在JavaScript与Java中使用正则表达式? ...

  2. mysql查询中使用别名_如何在MySQL选择查询中使用别名?

    要在MySQL中设置别名或替代名称,您需要使用AS关键字.让我们首先创建一个表-mysql> create table DemoTable ( Name varchar(100) ); 使用插入 ...

  3. sql server 数组_如何在SQL Server中实现类似数组的功能

    sql server 数组 介绍 (Introduction) I was training some Oracle DBAs in T-SQL and they asked me how to cr ...

  4. sql server 监视_如何在SQL Server中监视对象空间增长

    sql server 监视 介绍 (Introduction) There are many situations in a DBA's life that lead him or her to mo ...

  5. sql azure 语法_如何在SQL 2016中使用Azure Key Vault使用AlwaysOn配置TDE数据库

    sql azure 语法 One of the recent tasks I undertook on configuring Transparent Data encryption (TDE) us ...

  6. pb 修改数据窗口种指定字段位置_如何在PB数据窗口中修改数据---设置数据窗口的更新属性...

    如何在 PB 数据窗口中修改数据 --- 设置数据窗口的更新属性 数据窗口对象非常强大的原因之一就是能够很容易地修改数据库.当用户修 改了数据窗口中的数据,插入了新的数据行或者删除了数据行以后,只要调 ...

  7. kotlin数据库_如何在Kotlin应用程序中使用Xodus数据库

    kotlin数据库 I want to show you how to use one of my favorite database choices for Kotlin applications. ...

  8. mysql管理应用_如何在PHP和MySQL中制作出色的库存管理应用程序

    mysql管理应用 by Richard 理查德(Richard) 如何在PHP和MySQL中制作出色的库存管理应用程序 (How to Make an Awesome Inventory Manag ...

  9. sql初学者指南_使用tSQLt框架SQL单元测试面向初学者

    sql初学者指南 tSQLt is a powerful, open source framework for SQL Server unit testing. In this article, we ...

最新文章

  1. 对于tnsping的连接超时的功能补充
  2. Go web framework
  3. 前端怎么获取cookie的值_京东购物小程序cookie方案实践(附Demo)
  4. 字符串中的第一个唯一字符
  5. layui怎样将响应数据展示在页面_layui怎么对弹出层显示数据
  6. 编译自定义的主题theme
  7. 客户端触发PostBack回发的两种写法
  8. “威金(Worm.Viking)”病毒特点-专杀及_desktop.ini删除
  9. 某微型计算机字长为8位,单片机课后习题答案 - 图文
  10. JAVA音视频解决方案----JTT1078-2016文档梳理与一些难点梳理
  11. MongoDB中updateOne的正常使用
  12. cout和cin后面跟指针的问题
  13. 猴子选大王(python)
  14. 我的日记本开发手记(4)—— UI效果图
  15. 2022年全国职业院校技能大赛:网络系统管理项目 B模块-Windows部署(10套样题)
  16. 风力发电机组的温升问题如何解决呢?
  17. 高中计算机专业班主任工作总结,中等专业学校计算机班主任年工作总结
  18. 2021-08-15关于水卡数据算法,求助大神
  19. C++OO部分知识小结(1)
  20. iOS和Android使用同一个二维码自动跳转不同下载页面链接(附生成二维码地址方法)

热门文章

  1. .net 获取xml里面的值_XML技术
  2. webapi实现AJAX多文件上传,AJAX调用webapi上传图片或文件
  3. 怎么判断tcp重组完成_网络工程师(8):TCP为什么可靠
  4. 网站日志统计查询工具
  5. python面试题No2
  6. 二叉树链式结构实现C语言
  7. 输入url并按下回车的那一刻发生了什么?
  8. VScode配置C语言环境 亲测 可用!!!
  9. 前端—每天5道面试题(6)
  10. python 动态链接库_Python调用dll动态链接库(下)