我们每天通过 WAN 运送我们的 SQL Server 备份。我们需要最小化这些备份的大小,这样它就不会花很长时间。
我们不介意我们的备份过程是否需要更长的时间;目前,我们需要在 WAN 上移动 30gigs 的压缩备份,这需要 10 多个小时。
我们有两种选择来获得较小的每日备份。
两者都涉及我们的大量工作。我们使用的是 SQL Server 2008 pro,所有备份都是压缩的。
是否有任何商业产品可以为我们提供与选项 (2) 类似的备份大小?
是否有一个全面的脚本可以让我们完成(2)?(处理索引视图、过滤索引、外键等)
DBCC ShrinkDatabase()
DBCC ShrinkFile()
Run Code Online (Sandbox Code Playgroud)
这个问题是关于 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 在两个索引查找上执行哈希匹配。当您不知道如何搜索表时,这也许有意义?谢谢。
我正在查看此处的文章 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 次执行不会引发任何这些事件。(表变量版本没有得到任何这些事件) …
我有几个具有相同基本结构的非常大的桌子。每个都有一个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顺序加载, …
当我运行以下代码时,它需要 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) 我找了实际指导的设定值BUFFERCOUNT,BLOCKSIZE以及MAXTRANSFERSIZE该的BACKUP命令。我做了一些研究(见下文),我做了一些测试,我完全意识到任何真正有价值的答案都会以“好吧,这取决于……”开头。我对我所做的测试以及我发现的任何资源中显示的测试(见下文)的担忧是,测试是在真空中完成的,很可能是在没有其他负载的系统上完成的。
我很好奇关于这三个基于长期经验的选项的正确指导/最佳实践:数周或数月内的许多数据点。而且我不是在寻找特定值,因为这主要是可用硬件的功能,但我想知道:
BUFFERCOUNT* MAXTRANSFERSIZE) 不超过可用 RAM?可能的 I/O 争用?到目前为止我收集到的:
BLOCKSIZE:
如果手动设置,该值需要 >= 用于创建数据文件的块大小,否则您将收到以下错误:
消息 3272,级别 16,状态 0,第 3 行
“C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Backup\BackupTest.bak”设备的硬件扇区大小为 4096,但块大小参数指定不兼容的覆盖值 512。使用兼容的块大小重新发出语句。 …
SQL Server 2017 有几个新的存储过程:
以及 sys.messages 中的新条目:
在他对哪个更好的回答中:标识列还是生成的唯一 id 值?mrdenny 说:
当 SQL Denali 出现时,它将支持比身份更高效的序列,但您无法自己创建更高效的东西。
我不确定。知道 Oracle 的序列后,我要么为插入创建触发器,将每个插入封装到存储过程的调用中,要么祈祷我在执行临时插入时不要忘记正确使用序列。
我怀疑序列的优势是否如此明显。
这与计算符合特定条件的记录数有关,例如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 更可取有两个原因:
COUNTCOUNT 可能在i += 1某处涉及一个简单的操作,而 SUM 不能指望它的表达式是一个简单的整数值。有没有人有关于特定 RDBMS 差异的具体事实?
sql-server ×10
backup ×2
dbcc ×1
exists ×1
index-tuning ×1
maintenance ×1
mysql ×1
oracle ×1
performance ×1
postgresql ×1
primary-key ×1
sequence ×1
shrink ×1
sqlite ×1