标签: sql-server

最小的备份可能......使用 SQL Server

我们每天通过 WAN 运送我们的 SQL Server 备份。我们需要最小化这些备份的大小,这样它就不会花很长时间。

我们不介意我们的备份过程是否需要更长的时间;目前,我们需要在 WAN 上移动 30gigs 的压缩备份,这需要 10 多个小时。

我们有两种选择来获得较小的每日备份。

  1. 日志传送,这意味着我们必须重构 DR 流程。
  2. 从数据库中剥离信息并在另一侧重建(删除非聚集索引,100% 打包聚集索引 - 在另一侧重建)

两者都涉及我们的大量工作。我们使用的是 SQL Server 2008 pro,所有备份都是压缩的。

是否有任何商业产品可以为我们提供与选项 (2) 类似的备份大小?

是否有一个全面的脚本可以让我们完成(2)?(处理索引视图、过滤索引、外键等)

sql-server-2008 sql-server backup

37
推荐指数
5
解决办法
5945
查看次数

收缩数据库和文件有什么区别?

DBCC ShrinkDatabase()
DBCC ShrinkFile()
Run Code Online (Sandbox Code Playgroud)
  1. 我是否需要同时运行两个 DBCC 命令才能缩小数据库?
  2. 上面这两个有什么区别?

sql-server-2005 sql-server shrink dbcc

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

我应该使用多个单字段索引,而不是特定的多列索引吗?

这个问题是关于 SQL Server 索引技术的有效性。我认为它被称为“索引交集”。

我正在使用一个现有的 SQL Server (2008) 应用程序,该应用程序存在许多性能和稳定性问题。开发人员在索引方面做了一些奇怪的事情。我无法获得关于这些问题的结论性基准,也无法在互联网上找到任何真正好的文档。

表上有许多可搜索的列。开发人员在每个可搜索列上创建了一个单列索引。理论上,SQL Server 将能够组合(交叉)这些索引中的每一个,以在大多数情况下有效地访问表。这是一个简化示例(真实表有更多字段):

CREATE TABLE [dbo].[FatTable](
    [id] [bigint] IDENTITY(1,1) NOT NULL,
    [col1] [nchar](12) NOT NULL,
    [col2] [int] NOT NULL,
    [col3] [varchar](2000) NOT NULL, ...

CREATE NONCLUSTERED INDEX [IndexCol1] ON [dbo].[FatTable]  ( [col1] ASC )
CREATE NONCLUSTERED INDEX [IndexCol2] ON [dbo].[FatTable] ( [col2] ASC )

select * from fattable where col1 = '2004IN' 
select * from fattable where col1 = '2004IN' and col2 = 4
Run Code Online (Sandbox Code Playgroud)

我认为针对搜索条件的多列索引要好得多,但我可能错了。我看到查询计划显示 SQL Server 在两个索引查找上执行哈希匹配。当您不知道如何搜索表时,这也许有意义?谢谢。

sql-server-2008 sql-server index-tuning

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

为什么在这种特定情况下使用表变量的速度是 #temp 表的两倍多?

我正在查看此处的文章 Temporary Tables vs. Table Variables and their Effect on SQL Server Performance and on SQL Server 2008 能够重现与 2005 中显示的结果类似的结果。

当执行只有 10 行的存储过程(定义如下)时,表变量 version out 执行临时表 version 的两倍以上。

我清除了过程缓存并运行了两个存储过程 10,000 次,然后再重复该过程 4 次。结果如下(每批时间以毫秒为单位)

T2_Time     V2_Time
----------- -----------
8578        2718      
6641        2781    
6469        2813   
6766        2797
6156        2719
Run Code Online (Sandbox Code Playgroud)

我的问题是:表变量版本性能更好的原因什么?

我做了一些调查。例如查看性能计数器

SELECT cntr_value
from sys.dm_os_performance_counters
where counter_name = 'Temp Tables Creation Rate';
Run Code Online (Sandbox Code Playgroud)

确认在这两种情况下,临时对象都按预期在第一次运行后被缓存,而不是每次调用都从头开始创建。

类似地跟踪Profiler 中的Auto Stats, SP:Recompile,SQL:StmtRecompile事件(下面的屏幕截图)显示这些事件仅发生一次(在第一次调用#temp表存储过程时),其他 9,999 次执行不会引发任何这些事件。(表变量版本没有得到任何这些事件) …

sql-server temporary-tables

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

PK 索引中的列顺序重要吗?

我有几个具有相同基本结构的非常大的桌子。每个都有一个RowNumber (bigint)DataDate (date)列。每晚都使用 SQLBulkImport 加载数据,并且永远不会加载“新”数据 - 它是历史记录(SQL Standard,不是 Enterprise,因此没有分区)。

因为每一位数据都需要绑定回其他系统,并且每个RowNumber/DataDate组合都是唯一的,那就是我的主键。

我注意到,由于我在 SSMS 表设计器中定义 PK 的方式,RowNumber列在第一和DataDate第二位。

我还注意到我的碎片总是非常高~99%。

现在,因为每个DataDate只出现一次,我希望索引器每天只添加到页面,但我想知道它是否实际上是基于RowNumber第一个索引,因此必须改变其他所有内容?


Rownumber不是标识列,它是由外部系统生成的 int(遗憾的是)。它在每个 开始时重置DataDate

示例数据

RowNumber | DataDate | a | b | c..... 
   1      |2013-08-01| x | y | z 
   2      |2013-08-01| x | y | z 
...
   1      |2013-08-02| x | y | z 
   2      |2013-08-02| x | y | z 
...
Run Code Online (Sandbox Code Playgroud)

数据按RowNumber顺序加载, …

sql-server primary-key clustered-index sql-server-2008-r2

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

IF EXISTS 花费的时间比嵌入式 select 语句长

当我运行以下代码时,它需要 22.5 分钟并进行 1.06 亿次读取。但是,如果我只运行内部 select 语句本身,它只需要 15 秒并执行 264k 读取。作为旁注,选择查询不返回任何记录。

知道为什么IF EXISTS它会运行更长时间并进行更多读取吗?我还更改了 select 语句,SELECT TOP 1 [dlc].[id]并在 2 分钟后将其杀死。

作为临时修复,我已将其更改为执行 count( * ) 并将该值分配给变量@cnt。然后它做一个IF 0 <> @cnt声明。但我认为EXISTS会更好,因为如果在 select 语句中返回了记录,它会在找到至少一条记录后停止执行扫描/搜索,而count(*)将完成完整查询。我错过了什么?

IF EXISTS
   (SELECT [dlc].[ID]
   FROM TableDLC [dlc]
   JOIN TableD [d]
   ON [d].[ID] = [dlc].[ID]
   JOIN TableC [c]
   ON [c].[ID] = [d].[ID2]
   WHERE [c].[Name] <> [dlc].[Name])
BEGIN
   <do something>
END
Run Code Online (Sandbox Code Playgroud)

performance sql-server exists

37
推荐指数
2
解决办法
4518
查看次数

为 BACKUP 命令设置 BUFFERCOUNT、BLOCKSIZE 和 MAXTRANSFERSIZE

我找了实际指导的设定值BUFFERCOUNTBLOCKSIZE以及MAXTRANSFERSIZE该的BACKUP命令。我做了一些研究(见下文),我做了一些测试,我完全意识到任何真正有价值的答案都会以“好吧,这取决于……”开头。我对我所做的测试以及我发现的任何资源中显示的测试(见下文)的担忧是,测试是在真空中完成的,很可能是在没有其他负载的系统上完成的。

我很好奇关于这三个基于长期经验的选项的正确指导/最佳实践:数周或数月内的许多数据点。而且我不是在寻找特定值,因为这主要是可用硬件的功能,但我想知道:

  • 各种硬件/负载因素如何影响应该做什么。
  • 是否存在不应覆盖这些值中的任何一个的情况?
  • 是否存在覆盖任何不明显的陷阱?使用了太多内存和/或磁盘 I/O?恢复操作复杂吗?
  • 如果我有一台运行多个 SQL Server 实例的服务器(一个默认实例和两个命名实例),并且如果我同时运行所有 3 个实例的备份,这是否会影响我设置这些值的方式,而不是确保集体(BUFFERCOUNT* MAXTRANSFERSIZE) 不超过可用 RAM?可能的 I/O 争用?
  • 在同一台服务器上拥有三个实例并再次同时运行所有三个实例的备份的相同场景中,在每个实例中同时运行多个数据库的备份如何影响这些值的设置?这意味着,如果三个实例中的每一个都有 100 个数据库,则每个实例同时运行 2 或 3 个备份,这样就有 6 到 9 个备份同时运行。(在这种情况下,我有许多中小型数据库,而不是一些大型数据库。)

到目前为止我收集到的:

  • BLOCKSIZE

    • 支持的大小为 512、1024、2048、4096、8192、16384、32768 和 65536 (64 KB) 字节。[1]
    • 磁带设备的默认值为 65536,否则为 512 [1]
    • 如果您要进行备份并计划从 CD-ROM 复制和恢复,请指定 BLOCKSIZE=2048 [1]
    • 写入单个磁盘时,默认512就可以了;如果使用RAID阵列或SAN,则必须测试以查看默认或65536是否更好。[13(第 18 页)]
    • 如果手动设置,该值需要 >= 用于创建数据文件的块大小,否则您将收到以下错误:

      消息 3272,级别 16,状态 0,第 3 行
      “C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Backup\BackupTest.bak”设备的硬件扇区大小为 4096,但块大小参数指定不兼容的覆盖值 512。使用兼容的块大小重新发出语句。 …

sql-server backup best-practices maintenance

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

如何在 SQL Server 2017 中使用 SNAPSHOT_MATERIALIZATION 创建视图?

SQL Server 2017 有几个新的存储过程:

  • sp_refresh_single_snapshot_view – @view_name nvarchar(261) 的输入参数,@rgCode int
  • sp_refresh_snapshot_views – @rgCode int 的输入参数

以及 sys.messages 中的新条目:

  • 10149 – 无法在视图 '%.*ls' 上创建具有 SNAPSHOT_MATERIALIZATION 的索引,因为视图定义包含内存优化表。
  • 10642 – 无法为 '%.*ls' 上的索引 '%.*ls' 设置 SNAPSHOT_MATERIALIZATION,因为它仅适用于视图上的索引。
  • 10643 – 无法为 '%.*ls' 上的 '%.*ls' 设置 SNAPSHOT_MATERIALIZATION,因为它仅适用于视图上的聚集索引。
  • 10648 – 无法为 '%.*ls' 上的分区索引 '%.*ls' 设置 SNAPSHOT_MATERIALIZATION。
  • 10649 – 无法在具有 SNAPSHOT_MATERIALIZATION 的聚集索引 '%.*ls' 的 '%.*ls' 上创建非聚集索引 '%.*ls'。
  • 10650 – 刷新快照视图需要在数据库上启用快照隔离。
  • 3760 – 无法删除具有 SNAPSHOT_MATERIALIZATION 的视图 '%.*ls' 上的索引 '%.*ls'。
  • 4524 – 无法更改视图 '%.*ls',因为它具有快照实现。
  • 4525 – 在刷新视图之前无法对具有快照实现的视图 '%ls' 使用提示 '%ls'。 …

sql-server materialized-view sql-server-2017

37
推荐指数
1
解决办法
5293
查看次数

为什么 Denali 序列应该比身份列表现更好?

在他对哪个更好的回答中:标识列还是生成的唯一 id 值?mrdenny 说:

当 SQL Denali 出现时,它将支持比身份更高效的序列,但您无法自己创建更高效​​的东西。

我不确定。知道 Oracle 的序列后,我要么为插入创建触发器,将每个插入封装到存储过程的调用中,要么祈祷我在执行临时插入时不要忘记正确使用序列。

我怀疑序列的优势是否如此明显。

sql-server sequence sql-server-2012

36
推荐指数
2
解决办法
4003
查看次数

对于绝对性能,SUM 更快还是 COUNT?

这与计算符合特定条件的记录数有关,例如invoice amount > $100

我倾向于更喜欢

COUNT(CASE WHEN invoice_amount > 100 THEN 1 END)
Run Code Online (Sandbox Code Playgroud)

然而,这同样有效

SUM(CASE WHEN invoice_amount > 100 THEN 1 ELSE 0 END)
Run Code Online (Sandbox Code Playgroud)

我认为 COUNT 更可取有两个原因:

  1. 传达意图,即 COUNT
  2. COUNT 可能i += 1某处涉及一个简单的操作,而 SUM 不能指望它的表达式是一个简单的整数值。

有没有人有关于特定 RDBMS 差异的具体事实?

mysql postgresql sqlite oracle sql-server

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