标签: performance

在 INSERT 上使用 WITH TABLOCK 的好处

在某些情况下,INSERT INTO <tablename> (WITH TABLOCK)由于日志记录最少,执行 an会更快。这些情况包括将数据库置于BULK_LOGGED恢复模型中。

是否有任何其他潜在的性能优势,使用WITH TABLOCKINSERT的空白表时,数据库(tempdb数据库)使用SIMPLE恢复模式?

我正在使用 SQL Server 2012 标准版。

我的用例是在使用 的存储过程中创建然后立即填充临时表INSERT...SELECT,其中可能包含多达几百万行。我尽量避免这种tempdb滥用,但有时需要这样做。

我正在尝试构建一个需要 require 的案例TABLOCK。它似乎不会伤害任何东西,并且可能有好处。我试图弄清楚是否有足够的潜在好处将它添加到我们的代码库中的任何地方,我确信没有其他进程想要写入表。

我通常使用集群 PK 插入新创建的本地临时表,但有时会使用堆。

performance sql-server insert sql-server-2012

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

更新所有列的开销是多少,即使是那些没有改变的列

在更新一行时,许多 ORM 工具发出一个 UPDATE 语句,设置与该特定实体关联的每一列

优点是您可以轻松地批量更新语句,因为UPDATE无论您更改什么实体属性,语句都是相同的。此外,您甚至还可以使用服务器端和客户端语句缓存。

所以,如果我加载一个实体并且只设置一个属性:

Post post = entityManager.find(Post.class, 1L);
post.setScore(12);
Run Code Online (Sandbox Code Playgroud)

所有列都将被更改:

UPDATE post
SET    score = 12,
       title = 'High-Performance Java Persistence'
WHERE  id = 1
Run Code Online (Sandbox Code Playgroud)

现在,假设我们也有一个关于该title属性的索引,数据库难道不应该意识到该值无论如何都没有改变吗?

这篇文章中,Markus Winand 说:

所有列的更新显示了我们在前几节中已经观察到的相同模式:响应时间随着索引的增加而增加。

我想知道为什么会有这种开销,因为数据库将关联的数据页从磁盘加载到内存中,因此它可以确定是否需要更改列值。

即使对于索引,它也不会重新平衡任何内容,因为对于未更改的列,索引值不会更改,但它们已包含在 UPDATE 中。

是不是和冗余不变列关联的B+树索引也需要导航,数据库才意识到叶子值还是一样的?

当然,一些 ORM 工具允许您只更新更改的属性:

UPDATE post
SET    score = 12,
WHERE  id = 1
Run Code Online (Sandbox Code Playgroud)

但是,当不同行的不同属性更改时,这种类型的 UPDATE 可能并不总是从批量更新或语句缓存中受益。

performance index orm update

19
推荐指数
2
解决办法
7732
查看次数

强迫流不同

我有一张这样的表:

CREATE TABLE Updates
(
    UpdateId INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
    ObjectId INT NOT NULL
)
Run Code Online (Sandbox Code Playgroud)

本质上是跟踪 ID 增加的对象的更新。

该表的使用者将选择一个由 100 个不同对象 ID 组成的块,按UpdateId特定的UpdateId. 本质上,跟踪它停止的位置,然后查询任何更新。

我发现这是一个有趣的优化问题,因为我只能通过编写由于索引而碰巧做我想要的查询来生成最大优化的查询计划,但不保证我想要什么:

SELECT DISTINCT TOP 100 ObjectId
FROM Updates
WHERE UpdateId > @fromUpdateId
Run Code Online (Sandbox Code Playgroud)

@fromUpdateId存储过程参数在哪里。

有以下计划:

SELECT <- TOP <- Hash match (flow distinct, 100 rows touched) <- Index seek
Run Code Online (Sandbox Code Playgroud)

由于UpdateId正在使用索引上的搜索,结果已经很好,并且按照我想要的从最低到最高的更新 ID 排序。这会生成一个流程不同的计划,这就是我想要的。但是排序显然不能保证行为,所以我不想使用它。

这个技巧也会产生相同的查询计划(尽管有一个冗余的 TOP):

WITH ids AS
(
    SELECT ObjectId
    FROM Updates …
Run Code Online (Sandbox Code Playgroud)

performance sql-server optimization sql-server-2014 query-performance

19
推荐指数
3
解决办法
797
查看次数

为什么在 SQL Server 中“select *”比“select top 500 *”快?

我有一个观点,complicated_view-- 有一些连接和 where 子句。现在,

select * from complicated_view (9000 records)
Run Code Online (Sandbox Code Playgroud)

更快,更快,比

select top 500 * from complicated_view
Run Code Online (Sandbox Code Playgroud)

我们说的是 19 秒对 5+ 分钟。

第一个查询返回所有 9000 条记录。如何只获得前 500 名的时间长得可笑?

显然,我将在这里查看执行计划 ---- 但是一旦我弄清楚为什么SQL Server 以次优方式运行“前 500”,我该如何实际告诉它以快速方式运行计划,喜欢坐满桌?

当然,我可能不得不完全重写视图——但很奇怪。

基本上,我将此数据表连接到第 3 方软件,该软件使用select top 500 *无法修改的默认查询预先检查表。因此,除了将此视图转储到实际表中(非常草率)之外,我也无法绕过他们的“前 500 名”附录。

这是 SQL Server 2012。

编辑:不同意重复标志。另一个问题,顶部比所有的都快。这将是预期的行为,返回较少的行。我的情况正好相反。另外,我的理解是 Top 100 是一种与 Top 100+ 不同的算法。我什至不认为重复的问题有正确的答案。也就是说,TOP X 查询将在很早的时候对潜在的大量表进行排序,而不是在它们被聚合/过滤/等之后。为什么是一个谜,但如何显然存在。

performance sql-server execution-plan select top query-performance

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

检索日期范围的最有效方法

使用这样的表结构检索日期范围的最有效方法是什么?

create table SomeDateTable
(
    id int identity(1, 1) not null,
    StartDate datetime not null,
    EndDate datetime not null
)
go
Run Code Online (Sandbox Code Playgroud)

假设你想要既范围StartDateEndDate。因此,换句话说,如果StartDate介于@StartDateBeginand之间@StartDateEnd,并且EndDate介于@EndDateBeginand之间@EndDateEnd,则执行某些操作。

我知道有几种方法可以解决这个问题,但最建议的是什么?

performance sql-server query-performance

18
推荐指数
2
解决办法
3万
查看次数

PostgreSQL 索引缓存

我很难找到关于如何在 PostgreSQL 中缓存索引的“外行”解释,所以我想对这些假设中的任何一个或所有假设进行现实检查:

  1. PostgreSQL 索引,如行,存在于磁盘上,但可能会被缓存。
  2. 索引可能完全在缓存中,也可能根本不在缓存中。
  3. 它是否被缓存取决于它的使用频率(由查询规划器定义)。
  4. 出于这个原因,大多数“明智”的索引将一直在缓存中。
  5. 索引buffer cache与行位于相同的缓存(?)中,因此索引使用的缓存空间不可用于行。


我理解这一点的动机来自我问的另一个问题,其中建议可以在大部分数据永远不会被访问的表上使用部分索引

在开始之前,我想明确一点,使用部分索引会产生两个优势:

  1. 我们减少了缓存中索引的大小,为缓存中的行本身释放了更多空间。
  2. 我们减少了 B 树的大小,从而加快了查询响应。

postgresql performance cache index-tuning

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

JOIN 条件和 WHERE 条件之间是否存在执行差异?

这两个示例查询之间是否存在性能差异?

查询 1:

select count(*)
from   table1 a
join   table2 b
on     b.key_col=a.key_col
where  b.tag = 'Y'
Run Code Online (Sandbox Code Playgroud)

查询 2;

select count(*)
from   table1 a
join   table2 b
on     b.key_col=a.key_col
   and b.tag = 'Y'
Run Code Online (Sandbox Code Playgroud)

注意唯一的区别是补充条件的位置;第一个使用WHERE子句,第二个将条件添加到ON子句中。

当我在 Teradata 系统上运行这些查询时,解释计划是相同的,JOIN 步骤显示了每种情况下的附加条件。但是,在关于 MySQL 的这个 SO 问题上,其中一个答案表明首选第二种样式,因为WHERE在进行连接之后进行处理。

编码这样的查询时是否有一般规则要遵循?我猜它必须依赖于平台,因为它显然对我的数据库没有影响,但这也许只是 Teradata 的一个功能。而如果它与平台相关的,我非常喜欢弄几个文件的参考资料; 我真的不知道该找什么。

mysql performance oracle

18
推荐指数
1
解决办法
7208
查看次数

编写检查列是否为非 NULL 值或 NULL 的 SQL 查询的最佳方法

我有一个参数为 NULL 作为默认值的 SP,然后我想做这样的查询:

SELECT ...
FROM ...
WHERE a.Blah = @Blah AND (a.VersionId = @VersionId OR (@VersionId IS NULL AND a.VersionId IS NULL));
Run Code Online (Sandbox Code Playgroud)

WHERE上述检查两个非空值和一个NULL值@VersionId

在性能方面,改为使用IF语句并将查询复制到一个搜索非 NULL 的查询和另一个搜索 NULL 的查询中会不会更好?:

IF @VersionId IS NULL BEGIN
    SELECT ...
    FROM ...
    WHERE a.Blah = @Blah AND a.VersionId IS NULL;
ELSE BEGIN
    SELECT ...
    FROM ...
    WHERE a.Blah = @Blah AND a.VersionId = @VersionId;
END
Run Code Online (Sandbox Code Playgroud)

或者查询优化器使它本质上是一样的?

更新:

(注意:我使用的是 SQL Server)

(据我所知,a.VersionId = @VersionId这两种情况都不能使用,是吗?)

performance sql-server-2008

18
推荐指数
1
解决办法
8765
查看次数

更改数据库默认排序规则时 Latin1_General_BIN 性能影响

我已将数据库排序规则设置为Latin1_General_BIN, 以使字符串比较区分大小写。这会影响性能吗?对数据库中的 DML 或 DDL 操作有什么影响吗?数据库已存在,其中包含表。

performance sql-server collation sql-server-2008-r2 unicode performance-tuning

18
推荐指数
2
解决办法
3万
查看次数

索引对更新列不在索引中的更新语句的影响

我经常看到人们说索引变慢了updatedelete并且insert。这被用作笼统的陈述,就好像它是绝对的一样。

在调整我的数据库以提高性能的同时,我不断遇到这种情况,这对我来说在逻辑上似乎与该规则相矛盾,而且我找不到任何人以其他方式说或解释。

在 SQL Server 中,我相信/假定大多数其他 DBMS,您的索引是根据您指定的特定列创建的。插入和删除总是会影响整行,因此它们不可能不影响索引,但更新似乎更独特一些,它们只能专门影响某些列。

如果我有未包含在任何索引中的列并且我更新它们,它们是否会因为我在该表中的其他列上有索引而变慢?

例如,在我的User表中,我有一个或两个索引,主键是 Identity/Auto Increment 列,另一个可能是某个外键列。
如果我直接更新一个没有索引的列,比如他们的电话号码或地址,这个更新是否会变慢,因为我在这两种情况下的其他列上都有索引?我正在更新的列不在索引中,所以从逻辑上讲,索引不应该更新,不是吗?如果有的话,我认为如果我在 WHERE 子句中使用索引,它们会加速。

performance index sql-server update query-performance

18
推荐指数
2
解决办法
4万
查看次数