标签: optimization

SQL Server 是否为每一行评估一次函数?

我有一个这样的查询:

SELECT col1
FROM   MyTable
WHERE  
    DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE())) 
       BETWEEN col2 
       AND     col3
;
Run Code Online (Sandbox Code Playgroud)

这给出了与此类似的执行计划的工具提示:

执行工具提示

dateadd搜索谓词的一部分是否对查询中的每一行执行?或者 SQL Server 是否为整个查询计算一次值?

sql-server-2008 sql-server optimization sql-server-2008-r2

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

优化问题:复合聚簇键、标志条件和索引合并

三张表:

product:与列: ( a, g, ...a_lot_more... )

a: PK, clustered
g: bit-column
Run Code Online (Sandbox Code Playgroud)

main:与列: ( c, f, a, b, ...a_lot_more... )

c: PK, clustered
f: bit-column
(a, b): UQ 
Run Code Online (Sandbox Code Playgroud)

lookup 带列: ( a, b, c, i )

(a, b): PK, clustered
a: FK to product(a)
c: UQ, FK to main(c)
i: bit-column
Run Code Online (Sandbox Code Playgroud)

我找不到合适的连接索引:

FROM  
    product
  JOIN 
    lookup
      ON  lookup.a = product.a  
  JOIN
    main
      ON  main.c = lookup.c 
WHERE 
      product.g = 1
  AND
      main.f = 1
  AND 
      lookup.i = 1 …
Run Code Online (Sandbox Code Playgroud)

mysql optimization mysql-5.5

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

SQL Server 是如何生成加起来达到 6,000% 的查询执行计划的?

奇怪的执行计划

今天我在 The Heap 上,正在查看我认为可以改进的查询计划。然而,它创造了一些东西,动摇了我对 SQL Server 查询优化器的信念。如果甚至不能计数到 100%,我还可以信任它吗?

表的特点:

  • 聚集在非标识列上
  • 12 个索引,其中之一是相关date_entered
  • 60,000 条记录
  • 26列不同类型和长度
  • PAGE 压缩表

有没有人以前见过这个,是什么导致计划看起来如此扭曲?


以下来自 SQL Sentry Plan Explorer

SQL Sentry 计划资源管理器 - 图像 顶级运营

sql-server optimization ssms execution-plan sql-server-2012

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

如何改进行估计以减少溢出到 tempdb 的机会

我注意到,当 tempdb 事件溢出(导致查询缓慢)时,对于特定连接,行估计通常会偏离。我已经看到溢出事件发生在合并和散列连接中,它们通常将运行时间增加 3 到 10 倍。这个问题涉及如何在减少溢出事件机会的假设下改进行估计。

实际行数 40k。

对于此查询,计划显示错误的行估计(11.3 行):

select Value
  from Oav.ValueArray
 where ObjectId = (select convert(bigint, Value) NodeId
                     from Oav.ValueArray
                    where PropertyId = 3331  
                      and ObjectId = 3540233
                      and Sequence = 2)
   and PropertyId = 2840
option (recompile);
Run Code Online (Sandbox Code Playgroud)

对于此查询,计划显示了良好的行估计(56k 行):

declare @a bigint = (select convert(bigint, Value) NodeId
                       from Oav.ValueArray
                      where PropertyId = 3331
                        and ObjectId = 3540233
                        and Sequence = 2);

select Value
  from Oav.ValueArray
 where ObjectId = @a               
   and PropertyId = 2840
option (recompile); …
Run Code Online (Sandbox Code Playgroud)

join sql-server optimization

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

如何确定添加索引的成本/收益?

根据克雷格·林格的说法:

虽然在(或包括)引用端外键列上创建索引通常是个好主意,但这不是必需的。您添加的每个索引都会稍微减慢 DML 操作的速度,因此您需要为每个INSERT,UPDATE或支付性能成本DELETE。如果索引很少使用,它可能不值得拥有。

您如何确定添加索引的收益是否超过其成本?

您是否在添加索引之前/之后分析单元测试并检查整体性能提升?或者,还有更好的方法?

postgresql index optimization

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

从带有聚集索引的 SQL Server 表中删除数据期间 B-Tree 是否重新平衡?

我在 SQL Server 数据库中有一个表,主键上有一个聚集索引。该表有 100 万行。如果我从表中删除 10K 行,在执行删除操作期间索引会被重组吗?

删除操作是存储过程的一部分。一次,可以有多个客户端执行存储过程,但是每次运行都会删除它自己的一组行(由主键唯一标识)。当多个客户端执行该过程时,我会阻塞键锁(U 型)。阻塞锁属于同一个表中的一行,它不属于任何并发运行的事务。不应该有任何阻塞,因为每次运行都试图删除它自己的一组行。锁定升级不会发生,因为它已关闭。

我怀疑,删除操作一定会导致索引重新平衡,因此在重组过程中,它可以对表的任何行进行键锁定。

我真的很感激对此的任何意见。

index sql-server optimization

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

执行计划不使用 INDEX,它使用表扫描

我知道在使用索引或表扫描时,SQL Server 使用统计信息来查看哪个更好。

我有一个有 2000 万行的表。我在 (SnapshotKey, Measure) 和这个查询上有一个索引:

select Measure, SnapshotKey, MeasureBand
from t1
where Measure = 'FinanceFICOScore'
group by Measure, SnapshotKey, MeasureBand
Run Code Online (Sandbox Code Playgroud)

查询返回 500k 行。所以查询只选择了表中 2.5% 的行。

问题是为什么 SQL Server 不使用我拥有的非聚集索引,而是使用表扫描?

统计数据已更新。

值得一提的是,查询性能很好。

表扫描

表扫描

强制索引

力指数

表/索引结构

CREATE TABLE [t1](
    [SnapshotKey] [int] NOT NULL,
    [SnapshotDt] [date] NOT NULL,
    [Measure] [nvarchar](30) NOT NULL,
    [MeasureBand] [nvarchar](30) NOT NULL,
    -- and many more fields
) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)

表上没有PK,因为它是一个数据仓库。

CREATE NONCLUSTERED INDEX [nci_SnapshotKeyMeasure] ON [t1]
(
    [SnapshotKey] ASC,
    [Measure] ASC
)
Run Code Online (Sandbox Code Playgroud)

index sql-server optimization execution-plan sql-server-2012

10
推荐指数
3
解决办法
6846
查看次数

导致扫描的持久计算列

将常规列转换为持久计算列会导致此查询无法执行索引查找。为什么?

在多个 SQL Server 版本上进行了测试,包括 2016 SP1 CU1。

再现

问题在于table1, col7

表和查询是原始版本的部分(和简化)版本。我知道查询可以用不同的方式重写,并且出于某种原因避免了这个问题,但我们需要避免接触代码,为什么table1不能被搜索的问题仍然存在。

正如 Paul White 所展示的(谢谢!),如果强制执行,则搜索可用,所以问题是:为什么优化器不选择搜索,以及我们是否可以做一些不同的事情来使搜索按预期进行,而无需更改代码?

为了澄清有问题的部分,这是错误执行计划中的相关扫描:

计划

sql-server optimization execution-plan

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

根据变更日志计算库存数量

假设您有以下表结构:

LogId | ProductId | FromPositionId | ToPositionId | Date                 | Quantity
-----------------------------------------------------------------------------------
1     | 123       | 0              | 10002        | 2018-01-01 08:10:22  | 5
2     | 123       | 0              | 10003        | 2018-01-03 15:15:10  | 9
3     | 123       | 10002          | 10004        | 2018-01-07 21:08:56  | 3
4     | 123       | 10004          | 0            | 2018-02-09 10:03:23  | 1
Run Code Online (Sandbox Code Playgroud)

FromPositionId并且ToPositionId是股票头寸。某些位置 ID:s 具有特殊含义,例如0。事件 from 或 to0表示库存已创建或删除。From0可能是交货的库存,to0可能是发货的订单。

该表目前包含大约 550 …

sql-server optimization sql-server-2014 running-totals

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

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

长话短说,我们正在使用非常大的人员表中的值更新小型人员表。在最近的测试中,此更新需要大约 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
查看次数