我需要一个可以在(或作为)函数中使用并检索 n 值的所有组合的查询。我需要长度 k 的所有组合,其中 k = 1..n。
扩展样本输入和结果,因此输入有 3 个值而不是 2 - 但是,输入值的数量可能从 1 到 n 不等。
示例:输入:在多行中的一列中包含值的表
Value (nvarchar(500))
------
Ann
John
Mark
Run Code Online (Sandbox Code Playgroud)
输出#1:在一列中连接值的表
Ann
John
Mark
Ann,John
John,Mark
Ann,Mark
Ann,John,Mark
Run Code Online (Sandbox Code Playgroud) 我正在努力通过警告Operator usedtempdb最大限度地减少查询计划的排序操作成本to spill data during execution with spill level 2
我在溢出级别 1 的执行期间发现了几篇与溢出数据相关的帖子,但不是级别 2。级别 1 似乎是由过时的统计数据引起的,那么级别 2 呢?我找不到任何与level 2.
我发现这篇与排序警告相关的文章非常有趣:
我的 SQL 服务器?
Microsoft SQL Server 2014 (SP2) (KB3171021) - 12.0.5000.0 (X64) 2016 年 6 月 17 日 19:14:09 版权所有 (c) Microsoft Corporation Enterprise Edition(64 位),Windows NT 6.3(内部版本 9600:)(管理程序)
我的硬件?
运行以下查询以查找硬件:
-- 来自 SQL Server 2012 的硬件信息
SELECT cpu_count AS [Logical CPU Count], hyperthread_ratio AS …Run Code Online (Sandbox Code Playgroud) performance sql-server memory execution-plan sort-operator query-performance
我在 PCMag 中阅读了 Itzik Ben-Gan 的这些文章:
搜索,您应扫描第 I 部分:当优化器未优化
搜索时,您应扫描第 II 部分:升序键
我目前的所有分区表都存在“最大分组”问题。我们使用Itzik Ben-Gan 提供的技巧来获取 max(ID),但有时它不会运行:
DECLARE @MaxIDPartitionTable BIGINT
SELECT @MaxIDPartitionTable = ISNULL(MAX(IDPartitionedTable), 0)
FROM ( SELECT *
FROM ( SELECT partition_number PartitionNumber
FROM sys.partitions
WHERE object_id = OBJECT_ID('fct.MyTable')
AND index_id = 1
) T1
CROSS APPLY ( SELECT ISNULL(MAX(UpdatedID), 0) AS IDPartitionedTable
FROM fct.MyTable s
WHERE $PARTITION.PF_MyTable(s.PCTimeStamp) = PartitionNumber
AND UpdatedID <= @IDColumnThresholdValue
) AS o
) AS T2;
SELECT @MaxIDPartitionTable
Run Code Online (Sandbox Code Playgroud)
我得到这个计划
但是 45 分钟后,看看读数
reads …Run Code Online (Sandbox Code Playgroud) 比如说,我们有一个这样的查询:
select a.*,b.*
from
a join b
on a.col1=b.col1
and len(a.col1)=10
Run Code Online (Sandbox Code Playgroud)
假设上述查询使用 Hash Join 并具有残差,则探测键将为col1,残差将为len(a.col1)=10。
但是在查看另一个示例时,我可以看到探针和残差是同一列。以下是对我想说的内容的详细说明:
询问:
select *
from T1 join T2 on T1.a = T2.a
Run Code Online (Sandbox Code Playgroud)
执行计划,突出显示探测和残差:
测试数据:
create table T1 (a int, b int, x char(200))
create table T2 (a int, b int, x char(200))
set nocount on
declare @i int
set @i = 0
while @i < 1000
begin
insert T1 values (@i * 2, @i * 5, @i)
set @i = @i …Run Code Online (Sandbox Code Playgroud) performance sql-server execution-plan database-internals query-performance
我有一个存储过程,它通过覆盖索引从索引视图返回结果。通常,它运行得很快(~10 毫秒),有时它可以运行长达 8 秒。
这是一个随机执行示例(注意:这不是一个缓慢的执行,但是除了传递的值之外,查询文本是相同的):
declare @p2 dbo.IdentityType
insert into @p2 values(5710955)
insert into @p2 values(5710896)
insert into @p2 values(5710678)
insert into @p2 values(5710871)
insert into @p2 values(5711103)
insert into @p2 values(6215197)
insert into @p2 values(5710780)
exec ListingSearch_ByLocationAndStatus @statusType=1,@locationIds=@p2
Run Code Online (Sandbox Code Playgroud)
这是 SPROC:
ALTER PROCEDURE [dbo].[ListingSearch_ByLocationAndStatus]
@LocationIds IdentityType READONLY,
@StatusType TINYINT
AS
BEGIN
SET NOCOUNT ON;
SELECT -- lots of fields
FROM [dbo].[ListingSearchView][a] WITH (NOEXPAND)
INNER JOIN @LocationIds [b] ON [a].[LocationId] = [b].[Id]
WHERE [a].[StatusType] = @statusType
OPTION (RECOMPILE);
Run Code Online (Sandbox Code Playgroud)
(注意:我OPTION (RECOMPILE) …
performance sql-server sql-server-2012 azure-vm query-performance
有人向我建议,在 t-SQL 批处理中使用 IF 语句对性能有害。我试图找到一些确认或验证这个断言。我使用的是 SQL Server 2005 和 2008。
断言是以下批次:-
IF @parameter = 0
BEGIN
SELECT ... something
END
ELSE
BEGIN
SELECT ... something else
END
Run Code Online (Sandbox Code Playgroud)
SQL Server 无法重用生成的执行计划,因为下一次执行可能需要不同的分支。这意味着 SQL Server 将从执行计划中完全删除一个分支,因为它已经可以确定当前执行需要哪个分支。这是真的吗?
此外,在这种情况下会发生什么:-
IF EXISTS (SELECT ....)
BEGIN
SELECT ... something
END
ELSE
BEGIN
SELECT ... something else
END
Run Code Online (Sandbox Code Playgroud)
无法提前确定将执行哪个分支?
performance sql-server-2005 sql-server-2008 sql-server query-performance
我有一个带有“TOP (X)”子句的 SQL UPDATE 语句,我正在更新值的行大约有 40 亿行。当我使用“TOP (10)”时,我得到一个几乎立即执行的执行计划,但是当我使用“TOP (50)”或更大时,查询永远不会(至少,在我等待时不会)完成,并且它使用完全不同的执行计划。较小的查询使用带有一对索引查找和嵌套循环连接的非常简单的计划,其中完全相同的查询(在 UPDATE 语句的 TOP 子句中具有不同的行数)使用涉及两个不同索引查找的计划、表线轴、并行性和一堆其他复杂性。
我使用了“OPTION (USE PLAN...)”来强制它使用由较小查询生成的执行计划——当我这样做时,我可以在几秒钟内更新多达 100,000 行。我知道查询计划很好,但 SQL Server 只会在只涉及少量行时自行选择该计划 - 我的更新中任何相当大的行数都会导致次优计划。
我认为并行性可能是罪魁祸首,所以我设置MAXDOP 1了查询,但没有效果 - 这一步已经消失,但糟糕的选择/性能没有。我sp_updatestats今天早上也跑了,以确保这不是原因。
我附上了两个执行计划 - 越短的执行计划也越快。此外,这里是有问题的查询(值得注意的是,我包含的 SELECT 在小行数和大行数的情况下似乎都很快):
update top (10000) FactSubscriberUsage3
set AccountID = sma.CustomerID
--select top 50 f.AccountID, sma.CustomerID
from FactSubscriberUsage3 f
join dimTime t
on f.TimeID = t.TimeID
join #mac sma
on f.macid = sma.macid
and t.TimeValue between sma.StartDate and sma.enddate
where f.AccountID = 0 --There's a filtered index …Run Code Online (Sandbox Code Playgroud) 我编写了一个带有 SQL Server 后端的应用程序,用于收集和存储大量记录。我已经计算出,在高峰期,平均记录量大约为每天 3-40 亿条(运行 20 小时)。
我最初的解决方案(在我完成数据的实际计算之前)是让我的应用程序将记录插入到我的客户查询的同一个表中。显然,这会很快崩溃并烧毁,因为不可能查询插入了这么多记录的表。
我的第二个解决方案是使用 2 个数据库,一个用于应用程序接收的数据,另一个用于客户端就绪数据。
我的应用程序将接收数据,将其分成大约 10 万条记录的批次,然后批量插入到临时表中。在大约 100k 条记录之后,应用程序将使用与之前相同的架构即时创建另一个临时表,并开始插入到该表中。它将在具有 10 万条记录的作业表中创建一条记录,并且 SQL Server 端的存储过程会将数据从临时表移动到客户端就绪的生产表,然后删除我的应用程序创建的表临时表。
除了具有作业表的临时数据库外,两个数据库都具有相同的 5 个表集,具有相同的架构。临时数据库在大量记录将驻留的表上没有完整性约束、键、索引等。如下所示,表名是SignalValues_staging. 目标是让我的应用程序尽快将数据发送到 SQL Server。动态创建表以便轻松迁移的工作流程非常有效。
以下是我的临时数据库中的 5 个相关表,以及我的工作表:
我编写的存储过程处理从所有临时表中移动数据并将其插入到生产中。下面是我的存储过程的一部分,它从临时表插入到生产中:
-- Signalvalues jobs table.
SELECT *
,ROW_NUMBER() OVER (ORDER BY JobId) AS 'RowIndex'
INTO #JobsToProcess
FROM
(
SELECT JobId
,ProcessingComplete
,SignalValueStagingTableName AS 'TableName'
,(DATEDIFF(SECOND, (SELECT last_user_update
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID(DB_NAME())
AND OBJECT_ID = OBJECT_ID(SignalValueStagingTableName))
,GETUTCDATE())) SecondsSinceLastUpdate
FROM SignalValueJobs
) cte
WHERE cte.ProcessingComplete = 1 …Run Code Online (Sandbox Code Playgroud) 在分析数据库时,我遇到了一个视图,该视图引用了一些非确定性函数,对于此应用程序池中的每个连接,这些函数每分钟被访问1000-2500 次。一个简单的视图产生以下执行计划:SELECT
对于少于一千行且每隔几个月可能会看到一两行更改的视图来说,这似乎是一个复杂的计划。但以下其他注意事项会变得更糟:
UDFs 来构建字符串UDFs 以获取本地化语言的 ISO 代码UDF作为JOIN谓词INSERT/ UPDATE/DELETE在每个触发器来写入底层表CURSORS该EXEC存储过程作为参考更多的这些串建设UDF秒。这对我来说似乎很糟糕,但我只有几年的 TSQL 经验。也越来越好!
看来开发人员认为这是一个好主意,这样做是为了让存储的几百个字符串可以根据从UDF特定于模式的a 返回的字符串进行翻译。
这是堆栈中的一个视图,但它们都同样糟糕:
CREATE VIEW [UserWKStringI18N]
AS
SELECT b.WKType, b.WKIndex
, CASE
WHEN ISNULL(il.I18NID, N'') = N''
THEN id.I18NString
ELSE il.I18nString
END AS WKString
,CASE
WHEN ISNULL(il.I18NID, N'') …Run Code Online (Sandbox Code Playgroud) performance sql-server sql-server-2008-r2 view functions query-performance
这是一个我似乎无法找到答案的简单问题。
在性能方面,如果我有一个WHERE条款,例如a=0 and b=0 and ... z=0,如果我用 替换该条件,我会获得任何性能a+b+...+z=0吗?
换句话说,通过替换以下内容是否有任何性能提升
Select *
From MyTable
Where A=0 and B=0 and C=0 and D=0...
Run Code Online (Sandbox Code Playgroud)
和
Select *
From MyTable
Where A+B+C+D=0...
Run Code Online (Sandbox Code Playgroud)
我知道它可以依赖于索引,但为此目的,我们只说不存在索引。算术运算符 (+) 的性能是否比“OR”或“AND”逻辑运算符更好?
我的印象是加法比使用 AND 或 OR 的多个条件表现得更好。
在 420 万行的表上
返回行其中 A=0 B=0 和 C=0 -> 351748 行
添加 (A+B+C=0) 需要 5 秒,而逻辑条件 A=0 和 B=0 和 C=0 需要 11 秒。
返回行 其中 A<>0 B<>0 或 C<>0 -> 3829750 行 58 秒
返回行 …