小编Mar*_*ith的帖子

当构建端为空时,SQL Server 为什么/何时评估内部散列连接的探测端?

设置

DROP TABLE IF EXISTS #EmptyTable, #BigTable

CREATE TABLE #EmptyTable(A int);
CREATE TABLE #BigTable(A int);

INSERT INTO #BigTable
SELECT TOP 10000000 CRYPT_GEN_RANDOM(3)
FROM   sys.all_objects o1,
       sys.all_objects o2,
       sys.all_objects o3;
Run Code Online (Sandbox Code Playgroud)

询问

WITH agg
     AS (SELECT DISTINCT a
         FROM   #BigTable)
SELECT *
FROM   #EmptyTable E
       INNER HASH JOIN agg B
                    ON B.A = E.A;
Run Code Online (Sandbox Code Playgroud)

执行计划

在此处输入图片说明

问题

这是我今天之前没有注意到的现象的简化再现。我对内部散列连接的期望是,如果构建输入为空,则不应执行探测端,因为连接不会返回任何行。上面的示例与此相反,并从表中读取了 1000 万行。这使查询的执行时间增加了 2.196 秒 (99.9%)。

其他观察

  1. 使用OPTION (MAXDOP 1)执行计划从#BigTable. 该ActualExecutions0对哈希连接内所有的运营商。
  2. 对于查询SELECT * FROM #EmptyTable E INNER …

sql-server parallelism execution-plan sql-server-2017

11
推荐指数
1
解决办法
702
查看次数

format() 是一个不确定的内置字符串函数......对吗?

在我发布关于缺少相关文档的连接项目之前,有人会确认我不是在这里遗漏了什么吗?

format被列为字符串函数的文档页面上:

“所有内置字符串函数都是确定性的。” -字符串函数 (Transact-SQL)

format在相关页面上也没有提到不确定性:


但是,在尝试创建持久计算列时:

create table t (date_col date); 
insert into t values (getdate());
alter table t add date_formatted_01 as format(date_col,'YYYY') persisted;
Run Code Online (Sandbox Code Playgroud)

返回以下错误:

无法保留表 't' 中的计算列 'date_formatted_01',因为该列是不确定的。

该文件指出

如果未提供文化参数,则使用当前会话的语言。

但添加文化论点并不会改变事情

这也失败

alter table t add date_formatted_02 as format(date_col, 'd', 'en-US' ) persisted
Run Code Online (Sandbox Code Playgroud)

reextester 演示:http ://rextester.com/ZMS22966

dbfiddle.uk 演示:http ://dbfiddle.uk/?rdbms=sqlserver_next&fiddle=7fc57d1916e901cb561b551af144aed6

sql-server

10
推荐指数
2
解决办法
1129
查看次数

T-SQL - 循环遍历表直到满足条件的最有效方法是什么

T-SQL.

任务:

  1. 人们想进入电梯,每个人都有一定的体重。
  2. 排队等候的人的顺序由列轮次决定。
  3. 电梯的最大容量 <= 1000 磅。
  4. 在电梯变得太重之前,返回最后一个能够进入电梯的人的名字!
  5. 返回类型应该是表格

在此处输入图片说明

问题: 解决这个问题最有效的方法是什么?如果循环是正确的,还有改进的余地吗?

我使用了一个循环和 # 临时表,这里是我的解决方案:

set rowcount 0
-- THE SOURCE TABLE "LINE" HAS THE SAME SCHEMA AS #RESULT AND #TEMP
use Northwind
go

declare @sum int
declare @curr int
set @sum = 0
declare @id int

IF OBJECT_ID('tempdb..#temp','u') IS NOT NULL
    DROP TABLE #temp

IF OBJECT_ID('tempdb..#result','u') IS NOT NULL
    DROP TABLE #result

create table #result( 
    id int not null,
    [name] varchar(255) not null,
    weight int not null, …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql

10
推荐指数
2
解决办法
7万
查看次数

为什么这样更快,使用安全吗?(字母表中的第一个字母在哪里)

长话短说,我们正在使用非常大的人员表中的值更新小型人员表。在最近的测试中,此更新需要大约 5 分钟才能运行。

我们偶然发现了看似最愚蠢的优化方法,但它似乎完美无缺!相同的查询现在可以在不到 2 分钟的时间内运行并完美地产生相同的结果。

这是查询。最后一行被添加为“优化”。为什么查询时间急剧减少?我们错过了什么吗?这会导致将来出现问题吗?

UPDATE smallTbl
SET smallTbl.importantValue = largeTbl.importantValue
FROM smallTableOfPeople smallTbl
JOIN largeTableOfPeople largeTbl
    ON largeTbl.birth_date = smallTbl.birthDate
    AND DIFFERENCE(TRIM(smallTbl.last_name),TRIM(largeTbl.last_name)) = 4
    AND DIFFERENCE(TRIM(smallTbl.first_name),TRIM(largeTbl.first_name)) = 4
WHERE smallTbl.importantValue IS NULL
-- The following line is "the optimization"
AND LEFT(TRIM(largeTbl.last_name), 1) IN ('a','à','á','b','c','d','e','è','é','f','g','h','i','j','k','l','m','n','o','ô','ö','p','q','r','s','t','u','ü','v','w','x','y','z','æ','ä','ø','å')
Run Code Online (Sandbox Code Playgroud)

技术说明:我们知道要测试的字母列表可能需要更多的字母。我们也意识到使用“DIFFERENCE”时明显的误差幅度。

查询计划(常规): https : //www.brentozar.com/pastetheplan/?
id = rypV84y7V 查询计划(带“优化”):https : //www.brentozar.com/pastetheplan/?id=r1aC2my7E

sql-server optimization sql-server-2017

10
推荐指数
2
解决办法
1411
查看次数

在 SQL Server 中拥有大量空表分区是否会产生可观的开销?

我最近继承了一个使用日期分区的项目,其中每日计划任务实现了过去 30 天和未来 60 天的滑动窗口方案。

实际上,插入的数据SYSUTCDATETIME()用于分区列,因此未来的 60 个分区始终为空。

这是一个需要解决的问题还是我应该让睡狗撒谎?

sql-server partitioning

10
推荐指数
1
解决办法
647
查看次数

为什么使用本地临时表(而不是全局临时表或常规表)会影响查询优化器选择糟糕的查询计划?

这个问题带来了查询优化器在简单查询的现有谓词中选择不好的搜索谓词的情况。运行一些测试后,我得出的结论是,糟糕的决定是由于使用了本地临时表而不是全局临时表或常规表。

db fiddle:本地临时表全局临时表常规表

索引查找信息

我在临时表文档中找不到任何可以解释我们在使用本地临时表而不是全局临时表或常规表时看到的不同行为的特征。这有合乎逻辑的原因还是可能是错误?

sql-server execution-plan temporary-tables

10
推荐指数
1
解决办法
180
查看次数

查询计划重用需要架构资格吗?

在阅读这篇关于 SQL Server 中的计划缓存的文章时,我发现了一个我不知道的花絮:

...为了重用,批处理引用的对象不需要名称解析。例如,Sales.SalesOrderDetail 不需要名称解析,而 SalesOrderDetail 则需要,因为在多个架构中可能存在名为 SalesOrderDetail 的表。通常,由两部分组成的对象名称(即 schema.object)为计划重用提供了更多机会。

我正在寻找关于使用两部分对象名称的重要性的一些说明,因为“通常,两部分对象名称为计划重用提供了更多机会。”,但它首先说这是必要的。

更具体地说,我处理的大多数存储过程都在 dbo 模式中,并且只引用 dbo 对象,而没有指定 dbo 前缀。即使所有内容都使用默认模式,这些是否无法重用缓存的查询计划?

sql-server-2005 sql-server-2008

9
推荐指数
1
解决办法
1179
查看次数

我应该在 SQL Server 中嵌套依赖外部联接吗?

我听到了关于这方面的混合信息,希望得到权威或专家的意见。

如果我有多个LEFT OUTER JOINs ,每个都依赖于最后一个,嵌套它们更好吗?

对于一个人为的例子,JOINtoMyParent取决于JOINto MyChildhttp : //sqlfiddle.com/#!3/31022/5

SELECT
    {columns}
FROM
    MyGrandChild AS gc
LEFT OUTER JOIN
    MyChild AS c
        ON c.[Id] = gc.[ParentId]
LEFT OUTER JOIN
    MyParent AS p
        ON p.[id] = c.[ParentId]
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

http://sqlfiddle.com/#!3/31022/7相比

SELECT
    {columns}
FROM
    MyGrandChild AS gc
LEFT OUTER JOIN
    (
    MyChild AS c            
    LEFT OUTER JOIN
        MyParent AS p
            ON p.[id] = c.[ParentId]
    )
    ON c.[Id] = gc.[ParentId]
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

如上所示,这些在 SS2k8 中产生不同的查询计划

performance join sql-server-2008-r2

9
推荐指数
1
解决办法
800
查看次数

是否可以使用 OPENROWSET 导入固定宽度的 UTF8 编码文件?

我有一个包含以下内容的示例数据文件,并使用 UTF8 编码保存。

\n
oab~opqr\n\xc3\xb6ab~\xc3\xb6pqr\n\xc3\xb6ab~\xc3\xb6pqr\n
Run Code Online (Sandbox Code Playgroud)\n

该文件的格式是固定宽度,第 1 至第 3 列各分配 1 个字符,第 4 列保留 5 个字符。

\n

我创建了一个 XML 格式文件,如下所示

\n
<?xml version = "1.0"?>  \n<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">  \n   <RECORD>  \n      <FIELD xsi:type="CharFixed" ID="Col1" LENGTH="1"/>       \n      <FIELD xsi:type="CharFixed" ID="Col2" LENGTH="1"/> \n      <FIELD xsi:type="CharFixed" ID="Col3" LENGTH="1"/> \n      <FIELD xsi:type="CharFixed" ID="Col4" LENGTH="5"/> \n      <FIELD xsi:type="CharTerm" ID="LINE_BREAK" TERMINATOR="\\n"/> \n   </RECORD>  \n   <ROW>  \n      <COLUMN SOURCE="Col1" NAME="Col1" xsi:type="SQLNVARCHAR"/>  \n      <COLUMN SOURCE="Col2" NAME="Col2" xsi:type="SQLNVARCHAR"/> \n      <COLUMN SOURCE="Col3" NAME="Col3" xsi:type="SQLNVARCHAR"/>  \n      <COLUMN SOURCE="Col4" NAME="Col4" xsi:type="SQLNVARCHAR"/> …
Run Code Online (Sandbox Code Playgroud)

sql-server azure-sql-database encoding openrowset

9
推荐指数
2
解决办法
3030
查看次数

“常量表” - 这是常见的做法吗?

大学 SQL 课程,使用 John J. Patrick 所著的“SQL Fundamentals”一书。在第三章中,他谈到使用“常量表”向 select 语句添加列,其中所有行都具有相同的值。

例如,如果您有表“字符”,如下所示:

first_name  last_name  dept_code
----------- ---------- -------------------
Fred        Flintstone ROCKS
Barney      Rubble     ROCKS
Wilma       Flintstone FACEPALMING_AT_FRED
Run Code Online (Sandbox Code Playgroud)

并且您想要一个 SELECT 向所有行添加值为“BEDROCK”的列“hometown”,他建议在数据库中创建第二个表“temp”,

hometown
--------
BEDROCK
Run Code Online (Sandbox Code Playgroud)

然后做

SELECT first_name, last_name, dept_code, hometown FROM characters, temp
Run Code Online (Sandbox Code Playgroud)

这个想法是避免将字符串常量放在 SELECT 语句中,并且如果您有很多需要相同常量的 SELECT,更新一个表比更新 50 个查询更容易。

问题是,过去 15 年来我一直在使用 SQL 数据库,但我从未见过这种结构。它是我刚刚错过的完全常见的东西,还是在这个任务结束后我可以从我的记忆中抹去的东西?

best-practices

8
推荐指数
1
解决办法
2万
查看次数