标签: sql-server

如何在 SQL Server 中提示多对多连接?

我有 3 个“大”表,它们连接在一对列上(都是ints)。

  • 表 1 有大约 2 亿行
  • 表 2 有大约 150 万行
  • 表 3 有约 600 万行

每个表在Key1、上都有一个聚集索引Key2,然后还有一个列。Key1具有低基数并且非常偏斜。它总是在WHERE子句中被引用。条款中Key2从未提及WHERE。每个连接都是多对多的。

问题在于基数估计。每个连接的输出估计变而不是变大。当实际结果达到数百万时,这导致最终估计值低至数百。

我有什么办法可以让 CE 做出更好的估计吗?

SELECT 1
FROM Table1 t1
     JOIN Table2 t2
       ON t1.Key1 = t2.Key1
          AND t1.Key2 = t2.Key2
     JOIN Table3 t3
       ON t1.Key1 = t3.Key1
          AND t1.Key2 = t3.Key2
WHERE t1.Key1 = 1;
Run Code Online (Sandbox Code Playgroud)

我尝试过的解决方案:

  • 在 上创建多列统计信息Key1Key2
  • 创建大量 …

join sql-server many-to-many sql-server-2016 cardinality-estimates

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

从 SQL 表中删除数百万行

我必须从 221+ 百万行表中删除 16+ 百万条记录,而且执行速度非常慢。

如果您分享使以下代码更快的建议,我将不胜感激:

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

DECLARE @BATCHSIZE INT,
        @ITERATION INT,
        @TOTALROWS INT,
        @MSG VARCHAR(500);
SET DEADLOCK_PRIORITY LOW;
SET @BATCHSIZE = 4500;
SET @ITERATION = 0;
SET @TOTALROWS = 0;

BEGIN TRY
    BEGIN TRANSACTION;

    WHILE @BATCHSIZE > 0
        BEGIN
            DELETE TOP (@BATCHSIZE) FROM MySourceTable
            OUTPUT DELETED.*
            INTO MyBackupTable
            WHERE NOT EXISTS (
                                 SELECT NULL AS Empty
                                 FROM   dbo.vendor AS v
                                 WHERE  VendorId = v.Id
                             );

            SET @BATCHSIZE = @@ROWCOUNT;
            SET @ITERATION = @ITERATION + …
Run Code Online (Sandbox Code Playgroud)

performance sql-server delete query-performance

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

子树成本和性能时间之间的 SQL 关系

“SQL 最终子树成本”和“查询时间性能”之间的一般关系是什么?

示例:当优化查询并且它从子树成本 0.2 到 0.1 时,这是否意味着查询时间将快两倍?我在查询中没有看到这种情况。

我们有一个服务器,即使使用“设置统计时间”和“DBCC DROPCLEANBUFFERS”也无法真正衡量查询性能。服务器、事务、程序、后台项目中有不同的进程在进行。

谢谢,

performance database-design sql-server optimization performance-tuning

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

如何将 TempDB 文件移动到不同的驱动器或文件夹?

如何将我的TempDB 数据或日志文件从现在的任何位置移动到不同的驱动器或文件夹

sql-server t-sql tempdb datafile

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

如何透视 SQL Server 中的多个列?

将表格“展平”成单行的最佳方法是什么?

例如,使用下表:

+-----+-------+-------------+------------------+
| Id  | hProp | iDayOfMonth | dblTargetPercent |
+-----+-------+-------------+------------------+
| 117 |    10 |           5 |           0.1400 |
| 118 |    10 |          10 |           0.0500 |
| 119 |    10 |          15 |           0.0100 |
| 120 |    10 |          20 |           0.0100 |
+-----+-------+-------------+------------------+
Run Code Online (Sandbox Code Playgroud)

我想生成下表:

+-------+--------------+-------------------+--------------+-------------------+--------------+-------------------+--------------+-------------------+
| hProp | iDateTarget1 | dblPercentTarget1 | iDateTarget2 | dblPercentTarget2 | iDateTarget3 | dblPercentTarget3 | iDateTarget4 | dblPercentTarget4 |
+-------+--------------+-------------------+--------------+-------------------+--------------+-------------------+--------------+-------------------+
|    10 |            5 |              0.14 |           10 …
Run Code Online (Sandbox Code Playgroud)

sql-server pivot t-sql

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

理解 sys.objects、sys.system_objects 和 sys.sysobjects?

在这个问题中,我正在使用sys.sysobjects. 但是,提到的答案之一sys.system_objects。我只是想知道这些表之间有什么区别?

  • sys.objects
  • sys.system_objects
  • sys.sysobjects

sysobjects 有更多的东西。

> SELECT count(*) FROM sysobjects;
2312

> SELECT count(*) FROM sys.system_objects;
2201

> SELECT count(*) FROM sys.objects;
> 111

SELECT count(*)
FROM sys.sysobjects
WHERE NOT EXISTS (
  SELECT 1
  FROM sys.system_objects
  WHERE system_objects.object_id = sysobjects.id
);
> 111
Run Code Online (Sandbox Code Playgroud)

sql-server database-internals system-tables

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

当表上有两个唯一索引且一个索引中的所有列也在另一个索引中时,是否会造成性能损失?

在我的数据库中,我有一个带有两个索引的表。出于数据完整性原因,a、b 列上有一个唯一索引 #1。我有另一个索引 #2,其中包含 c、a、b 列,用于性能原因。我注意到这个索引#2 也是唯一的。

在我看来,索引#2 的唯一性似乎是多余的,因为索引#2 中不可能有重复值,而索引#1 中也不可能有重复值。我很想更改索引 #2,使其不再唯一,因为我想象数据库引擎可能会对索引 #2 中的 c、a、b 执行第二次检查,以确保每次插入行时这些列的唯一性,从而导致即使永远不会有重复的值,也会影响性能。它是否正确?

有没有办法删除 a、b 上的索引 #1 并保留 c、a、b 上的索引 #2,但仍然只对 a、b 列施加唯一约束,而不维护两个单独的索引?这将允许我只有一个索引包含所有三列,但仍然对 a、b 强制执行数据完整性约束。为了提高性能,我不需要在 a、b 上建立索引,因为我所有的选择查询都在 where 子句中包含 c 列。这是否是唯一约束而不是索引的用例?我认为数据库引擎基本上以相同的方式对待这两个构造(请参阅这篇文章:何时应该使用唯一约束而不是唯一索引?)。

请记住,索引不是冗余的,但索引的“唯一性”是冗余的。看起来让索引 #2 变得不唯一是理所当然的。但这会带来任何实际的性能提升吗?即使索引 #1 中的列完全包含在索引 #2 中,数据库是否检查两个索引的唯一性?

一些答案询问了用于从此表中选择数据的示例查询。以下是最常见的:

Select [some other columns] from table where c=1 and a=2
Select [some other columns] from table where c=1
Select [some other columns] from table where c=1 and a=2 and b=3
Run Code Online (Sandbox Code Playgroud)

这些查询通常包括选择不在任何索引中的许多其他列。

我们通常不会运行这样的查询:

Select [stuff] from table …
Run Code Online (Sandbox Code Playgroud)

sql-server index-tuning unique-constraint

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

SQL Server 如何更新索引视图?

每次在索引视图引用的基表中插入、更新或删除数据时,数据库引擎都会自动更新索引视图以反映更改。但是,我不太确定数据库引擎如何更新索引视图。它是否完全重新运行视图中的查询,或者是否使用更有效的方法仅更新相应的部分?

sql-server materialized-view

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

创建索引然后删除它是否会使数据库返回到索引创建前的状态?

我正在测试一些索引,并希望对哪些索引表现更好(主要是索引中字段的顺序和指定的其他字段)进行一些 AB 测试。

我有正在测试的数据库的备份,但该备份需要很长时间才能恢复。我更希望能够创建索引 foo,收集性能指标,然后删除 foo 以将数据库返回到索引前状态并创建索引 bar。这是索引创建的工作方式,还是索引的创建会以某种方式改变表,而删除索引无法撤消?

index sql-server index-tuning

9
推荐指数
3
解决办法
1749
查看次数

运行 sys.fn_dump_dblog 时,WITH EXECUTE AS SELF 返回错误

我正在尝试将存储过程配置为 EXECUTE AS 具有 sysadmin 权限的用户,以允许非特权用户从未记录的 TVF 获取结果sys.fn_dump_dblog

我正在作为角色成员创建该过程sysadmin,但是当我随后尝试使用该子句运行该过程时WITH EXECUTE AS SELF,出现以下错误:

消息 9011,级别 14,状态 1,过程 dbo.read_log,第 16 行 [批处理开始第 65 行] 用户无权使用虚拟表 DBLog 查询备份文件。只有 sysadmin 固定服务器角色的成员才有此权限

这对我来说似乎很奇怪,因为我是服务器角色的成员sysadmin,并且WITH EXECUTE AS SELF在过程定义中指定子句应该会导致使用我的用户帐户执行该过程。根据学习网站

EXECUTE AS SELF 相当于 EXECUTE AS user_name,其中指定的用户是创建或更改模块的人。创建或修改模块的人员的实际用户 ID 存储在 sys.sql_modules 或 sys.service_queues 目录视图的execute_as_principal_id 列中。

如果我WITH EXECUTE AS SELF从过程的定义中删除该子句,TVF 将按预期返回结果。

以下是SQL Server 2019 中的最小、完整且可验证的示例。

首先,证明我们是该sysadmin角色的成员:

USE [master];
GO
SELECT 
      [roles].[name]
FROM sys.server_principals [members] …
Run Code Online (Sandbox Code Playgroud)

sql-server permissions sql-server-2019

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