Sto*_*orm 7 t-sql sql-server database-performance
我知道有很多这些问题,但我找不到与我的问题有关的问题.
看看这个问题,将IF EXIST(SELECT 1 FROM)更改为IF EXIST(SELECT TOP 1 FROM)是否有任何副作用?
在答案中特别提到这一节:
select * from sys.objects
select top 1 * from sys.objects
select 1 where exists(select * from sys.objects)
select 1 where exists(select top 1 * from sys.objects)
Run Code Online (Sandbox Code Playgroud)
我正在运行一些自己的测试来正确理解它.如答案所示:
select 1 where exists(select top 1 * from sys.objects)
select 1 where exists(select top 1 1 from sys.objects)
Run Code Online (Sandbox Code Playgroud)
两者都导致相同的执行计划,并导致相同的计划
select 1 where exists(select * from sys.objects)
select 1 where exists(select 1 from sys.objects)
Run Code Online (Sandbox Code Playgroud)
从我对这个问题的研究,"SELECT TOP 1 1"VS"IF EXISTS(SELECT 1".我推断这是商定的最佳实践:
select 1 where exists(select * from sys.objects)
Run Code Online (Sandbox Code Playgroud)
我的第一个问题是为什么这比这更受欢迎:
select 1 where exists(select 1 from sys.objects)
Run Code Online (Sandbox Code Playgroud)
在试图理解它时,我将它们分解为更基本的表达式(我使用'前1'来模仿类似存在的执行计划):
select top 1 * from sys.objects
select top 1 1 from sys.objects
Run Code Online (Sandbox Code Playgroud)
我现在看到第一个是执行时间的80%(相对于批次为2),而第二个只有20%.那么使用它会不是更好的做法
select 1 where exists(select 1 from sys.objects)
Run Code Online (Sandbox Code Playgroud)
因为它可以应用于两种情况,从而减少可能的人为错误?
SQL Server EXISTS在查询编译/优化过程中相对较早地检测谓词,并消除了对这些子句的实际数据检索,将其替换为存在检查.所以你的假设:
我现在看到第一个是执行时间的80%(相对于批次为2),而第二个只有20%.
是错误的,因为在前面的比较中,您实际上已经检索了一些数据,如果将查询放入(not) exists谓词中,则不会发生这种情况.
大多数时候,除了一个重要的捕获之外,如何测试行的存在没有区别.假设你说:
if exists (select * from dbo.SomeTable)
...
Run Code Online (Sandbox Code Playgroud)
代码模块中的某个地方(视图,存储过程,函数等).然后,当其他人决定将WITH SCHEMABINDING子句放入此代码模块时,SQL Server将不允许它,而不是可能绑定到当前列列表,它将引发错误:
消息1054,级别15,状态7,过程BoundView,第6行
语法绑定对象中不允许使用语法'*'.
简而言之:
if exists (select 0 from ...)
Run Code Online (Sandbox Code Playgroud)
是一种最安全,最快速,最适合所有存在检查的方式.
这两者的区别:
select top 1 * from sys.objects
select top 1 1 from sys.objects
Run Code Online (Sandbox Code Playgroud)
在第一个子句中,SQL Server 必须从表中获取所有列(从任何随机行),但在第二个子句中,可以从任何索引中获取“1”。
当这些子句位于exists子句内时,情况会发生变化,因为在这种情况下,SQL Server 知道它实际上不必获取数据,因为它不会分配给任何内容,因此它可以以与select *处理select 1.
由于存在仅检查一行,因此它内置了内部 top 1,因此手动添加它不会改变任何内容。
存在子句中的“天气”select *或select 1“天气”仅基于意见,您当然可以使用 2 或“X”或任何您喜欢的内容来代替 1。我个人总是使用... and exists (select 1 ...
| 归档时间: |
|
| 查看次数: |
20568 次 |
| 最近记录: |