小编cro*_*sek的帖子

如何使用合并提示隔离 SQL Server 中的复杂查询

我可以理解,如果我加入“单独快速”的单个查询,组合可能会变慢,因为默认执行计划可能不是最佳的。但是,当我知道一个查询的行数非常少时,我想我应该能够使用提示来控制连接。

select cj.a, cv.b
  from (select distinct a from complexJoin) cj -- 2 rows
 inner loop join complexView cv
    on cj.a = cv.a
 order by cj.a, cv.b
Run Code Online (Sandbox Code Playgroud)

如果 cj <1s 和 cv <1s 期望这是 <~2s 但使用任何提示(合并/散列/循环)通常> 1分钟。

我还尝试使用 CROSS APPLY,因为文档声称内部选择对于每个外部行只执行一次。该查询比手动运行两次内部查询需要大约 100 倍的时间,所以也许我不理解文档。

select cj.a, cv.b
  from (select distinct a from complexJoin) cj -- 2 rows
 cross apply (select * from complexView 
               where a = cj.a) cv
 order by cj.a, cv.b
Run Code Online (Sandbox Code Playgroud)

如果我用“cj”的结果填充临时表,然后加入 _with_no_hint_ 或使用交叉应用,它会很快,但我真的必须求助于它吗?如果我使用临时表并尝试“任何”连接提示(循环/合并/散列),它会很慢,所以这可能是一个关键点。

我不相信深入查询计划的深度(两者都是复杂的开始)是解决一般问题所必需的:我只想保证隔离而不诉诸临时表 - 这真的不可能?

join sql-server optimization hints merge

6
推荐指数
1
解决办法
1010
查看次数

查询真实的物理数据库文件大小

关于查询数据库文件大小...

1) 大多数(如果不是全部)这些答案并不总是与文件资源管理器中显示的物理文件大小匹配:

/sf/ask/416175231/

接受的答案报告:      从接受的答案

对比

2)这篇文章似乎与文件资源管理器中显示的物理文件大小相符:

    在此处输入图片说明

是否有一个查询可以在不依赖 dm_os_performance_counters 的情况下报告物理大小?第一组查询是否忽略了可用空间?

文件资源管理器报告的实际大小:

    在此处输入图片说明

为什么 Tempdb 显示的数据和日志文件大小都存在差异,如图所示?

Microsoft SQL Server 2012 (SP3) (KB3072779) - 11.0.6020.0 (X64)

sql-server database-size

5
推荐指数
1
解决办法
8794
查看次数

为什么递归 CTE 估计只有 1 行?

给定两个级联的、独立的(没有真正的表)递归 CTE:

create view NumberSequence_0_100_View
as
with NumberSequence as
(
    select 0 as Number
    union all
    select Number + 1
      from NumberSequence    
     where Number < 100
)
select Number
  from NumberSequence;
go

create view NumberSequence_0_10000_View
as
select top 10001
       v100.Number * 100 + v1.Number as Number
  from Common.NumberSequence_0_100_View v100
 cross join Common.NumberSequence_0_100_View v1
 where v1.Number < 100
   and v100.Number * 100 + v1.Number <= 10000
    -- please resist complaining about "order by in view" for this question
 order by v100.Number …
Run Code Online (Sandbox Code Playgroud)

sql-server cte sql-server-2012 recursive cardinality-estimates

4
推荐指数
1
解决办法
780
查看次数

为死锁扩展事件读取 system_health event_file 而不是 ring_buffer

我目前正在使用此灾难通过读取system_health扩展事件环形缓冲区来定位最近的死锁。

select top 2000000000
      XEvent.value('@timestamp', 'datetime2(3)') as CreationDateUtc,
      --
      -- Extract the <deadlock>...</deadlock> tag from within the event
      -- Todo: Surely there is a better (xml) way to do this.
      --
      substring(convert(varchar(max), XEvent.query('.')), 
          -- start
          patindex('%<deadlock%', convert(varchar(max), XEvent.query('.'))),          
          -- end
          patindex('%</deadlock%', convert(varchar(max), XEvent.query('.'))) -
              patindex('%<deadlock%', convert(varchar(max), XEvent.query('.'))) + 11 -- 11 to include for '</deadlock>'
          ) AS XdlFile
 from 
    (
      select cast (target_data as xml) as TargetData
        from sys.dm_xe_session_targets st with (nolock)
        join sys.dm_xe_sessions s with (nolock)
          on …
Run Code Online (Sandbox Code Playgroud)

xml sql-server deadlock extended-events sql-server-2012

4
推荐指数
1
解决办法
2257
查看次数

如何控制非聚集列存储索引上的分段最小/最大 data_id

给定一个简单的基于行的表,没有 PK 但有一个基于行的聚集索引,如下所示:

create clustered index [CX_PropertyValue] ON [dbo].[PropertyValue] ([PropertyId], [Value])
Run Code Online (Sandbox Code Playgroud)

然后我希望添加一个列存储索引,该索引按与上面的聚集索引相同的顺序进行分段:

create nonclustered columnstore index CS_IX_PropertyValue on dbo.PropertyValue( 
    PropertyId, Value
)
with (drop_existing = on, maxdop = 1); -- maxdop=1 to preserve the order by property 
Run Code Online (Sandbox Code Playgroud)

MaxDop 保留顺序的提示来自:这里

然后使用以下查询报告 PropertyId 列的最小/最大 data_id,并报告 7 个段中的每个段的完整范围:

create view [Common].[ColumnStoreSegmentationView]
as
/*---------------------------------------------------------------------------------------------------------------------
    Purpose: List ColumnStore table segment min/max of columns.

     Source: https://joyfulcraftsmen.com/blog/cci-how-to-load-data-for-better-columnstore-segment-elimination/
             https://dba.stackexchange.com/a/268329/9415

    Modified    By            Description
    ----------  ----------    -----------------------------------------------------------------------------------------
    2020.06.02  crokusek/inet Initial Version 
  ---------------------------------------------------------------------------------------------------------------------*/
select --top 20000000000
       s.Name as SchemaName, 
       t.Name …
Run Code Online (Sandbox Code Playgroud)

sql-server columnstore sql-server-2019

4
推荐指数
1
解决办法
136
查看次数

无法在 SQL Server 上并行运行联合

我无法得到这个相当简单的查询来并行化联合操作:

select va.ObjectId, 0 as IsFlag
  from Oav.ValueArray va     
 where va.PropertyId = @pPropertyId                
   and va.value in (select value from #MatchValues)                  
 group by va.ObjectId
having count(distinct va.Value) = (select count(*) from #MatchValues)

union all    

select odv.ObjectId, 1 as IsFlag
  from Pub.OtherTable codv
 where PropertyId = 2551
   and Id in (select value from #Ids) 
   and Flag = @pFlag
   and Value in (select value from #MatchValues)
 group by codv.ObjectId
having count(distinct codv.Value) = (select count(*) from #MatchValues)
Run Code Online (Sandbox Code Playgroud)

使用 MAXDOP 1 运行会得到预期的 0.8s (.5 …

sql-server union

3
推荐指数
1
解决办法
2034
查看次数

给定两个带有 SpillToTempDb 警告的查询计划,如何确定运行时间增加的原因

为一个查询的两次执行捕获了两个实际的查询计划:

计划“快速”花费了大约 1 秒,大约 90% 的时间都会发生。

计划“慢”花了大约 16 秒。

由于图形计划看起来与我相同,因此我转储了 XML 版本并执行了差异以查看文本差异以确保。

快侧有 2 个“SpillToTempDb”警告,慢侧有 4 个警告。看着 2 个额外的慢端:

One SpillToTempDb warning on "Parallelism (Repartition Streams) Cost 1%":

    <SpillToTempDb SpillLevel="0" />

On SpillToTempDb warning on "Parallelism (Distribute Streams) Cost 1%":

    <SpillToTempDb SpillLevel="0" />
Run Code Online (Sandbox Code Playgroud)

慢速和快速情况下的成本是相同的 (1%)。这是否意味着可以忽略警告?有没有办法显示“实际”时间或成本。那会好很多!对于溢出操作,实际行数是相同的。

除了执行 xml 执行计划的手动文本差异以查找警告中的差异之外,我怎么知道运行时间增加 1500% 的实际原因是什么?

除了“RunTimeCountersPerThread”行之外的差异:

Left file: C:\Users\chrisr\Desktop\fast.sqlplan     Right file: C:\Users\chrisr\Desktop\slow.sqlplan
10                    <ThreadStat Branches="10" UsedThreads="85">
     10               <ThreadStat Branches="10" UsedThreads="73">
------------------------------------------------------------------------
------------------------------------------------------------------------
19                    <MemoryGrantInfo SerialRequiredMemory="1536" SerialDesiredMemory="10816" RequiredMemory="124224" DesiredMemory="133536" RequestedMemory="133536" GrantWaitTime="0" GrantedMemory="133536" MaxUsedMemory="105440" />
     19               <MemoryGrantInfo …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan tempdb

3
推荐指数
1
解决办法
923
查看次数

如何由于连接 2 个良好估计的结果而更正行估计

以下查询在约 60 个数据库上并行运行。在没有提示的情况下,至少 10% 的数据库存在大量溢出和非最佳计划。

使用更大的数据库作为指导,查询被锁定并带有提示(1 个 CPU 上约 75 毫秒),以减少运行时的差异,因为 1 个错误的计划会导致整体运行时间终止。我们主要反对让每个DB自由调整其计划,因为从长远来看,某些DB可能会在生产平台上着火。我们对大型数据库的近乎最佳计划感到非常满意,但对于较小的数据库可能不是最佳的。

即使在添加带有完整扫描的统计信息后,一些(~5)较小的数据库仍然表现出小的 1 级溢出(参见计划)。运行时间仍然可以(125 毫秒),但希望消除溢出。

这是 Sql Server 2019。自适应授权功能 (2017) 是否应该因溢出而调整授权?在 SSMS 和查看计划中重复运行它似乎表明没有变化。

select top (@pMax)
           aig.ObjectId,  
           iif((@pA in (1, 2, 3, 4, 5, 6, 9, 11, 12) and ttm.ObjectId is not null) or
               (@pA in (7, 8, 10, 13, 14, 15)), 1.0, 0.0) as Rank
      from oav.value aig               
      inner merge join Pub.CachedObjectHierarchyAttributes coha
        on coha.ObjectId = aig.ObjectId
       and coha.IsActiveForPublisher = 1
       and coha.IsToolItem = 1
      inner merge …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan cardinality-estimates query-performance

3
推荐指数
1
解决办法
246
查看次数

如何将 Convert() 评估延迟到加入之后

以下查询转换表示 13k 行 x 2 列的打包 CSV 的单个字符串。A 列是一个 bigint。B 列是一个smallint。

declare
    @dataCsv nvarchar(max) = '29653,36,19603,36,19604,36,29654,36';  -- abbreviated, actually 13k rows

  with Input as
  (
      select Value,
             Row = row_number() over (order by (select null)) - 1
      from string_split(@dataCsv, ',') o
  )
  --insert into PubCache.TableName
  select 78064 as CacheId,
         convert(bigint, i.Value) as ObjectId,
         convert(smallint, i2.Value) as BrandId
    from Input i
    inner hash join Input i2    -- hash to encourage string_split() only once per column
      on i2.Row = i.Row + 1 …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan type-conversion string-splitting

3
推荐指数
1
解决办法
551
查看次数

如何提高新插入数据联接中 1 行的行估计值

表的 CacheId 列存在自定义统计信息。隔夜统计更新后:

Statistics for INDEX 'ST_TableName_CacheId'.
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Name                            Updated                         Rows                            Rows Sampled                    Steps                           Density                         Average Key Length              String Index                    
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ST_TableName_CacheId Apr 26 2014  2:04AM             121482                          121482                          6                               0                               4                               NO                                                              121482                          

All Density                     Average Length                  Columns                         
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0.1666667                       4                               CacheId                         

Histogram Steps                 
RANGE_HI_KEY                    RANGE_ROWS                      EQ_ROWS                         DISTINCT_RANGE_ROWS             AVG_RANGE_ROWS                  
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
39968                           0                               20247                           0                               1                               
40058                           0                               20247                           0                               1                               
40062                           0                               20247                           0                               1                               
40066                           0                               20247                           0                               1                               
40069                           0                               20247                           0                               1                               
41033                           0                               20247                           0                               1 …
Run Code Online (Sandbox Code Playgroud)

sql-server optimization statistics cardinality-estimates

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

如何改进 RAMDisk 上的 TempDb 显示与物理硬盘驱动器相当的性能

给定 2 个 SQL Server 实例,其中第二个实例配置有用于 tempdb 的 RAMDisk 和以下测试用例。

-- Create source data
select top(1000000) * /* ~10 cols */ into #t1 from SomeData;
Run Code Online (Sandbox Code Playgroud)

然后测量这些级联选择的总运行时间;

-- Benchmark  
select * into #t4 from #t1;
select * into #t5 from #t4;
select * into #t6 from #t5;
Run Code Online (Sandbox Code Playgroud)

我的运行时间是一样的~(15s vs ~15s)。一个 CPU 在整个测试期间都达到最大值。

有没有办法加快跨 CPU 的查询(是 tempdb 文件分区)吗?

通过评论请求数据:

The 1 CPU is the SQL Server 2012 process on a 12 CPU server circa 2012.
Machine: 24GMb RAM, HardDrives: 10kRpm x 2 …
Run Code Online (Sandbox Code Playgroud)

sql-server optimization tempdb

-4
推荐指数
1
解决办法
1852
查看次数