小编Stu*_*ler的帖子

什么时候应该将主键声明为非聚集的?

在为我之前问的另一个问题创建测试数据库时,我记得可以声明主键 NONCLUSTERED

什么时候使用NONCLUSTERED主键而不是CLUSTERED主键?

提前致谢

sql-server primary-key

188
推荐指数
4
解决办法
14万
查看次数

删除与截断

我试图更好地了解DELETETRUNCATE命令之间的差异。我对内部结构的理解大致如下:

DELETE-> 数据库引擎从相关数据页和输入该行的所有索引页中查找并删除该行。因此,索引越多,删除所需的时间就越长。

TRUNCATE -> 简单地删除所有表的数据页,使其成为删除表内容的更有效选项。

假设以上是正确的(如果不正确,请纠正我):

  1. 不同的恢复模式如何影响每个语句?如果有任何影响
  2. 删除时,是扫描所有索引还是仅扫描行所在的索引?我假设所有索引都被扫描(而不是搜索?)
  3. 命令是如何复制的?是否在每个订阅者上发送和处理 SQL 命令?还是 MSSQL 比这更智能一点?

sql-server database-internals

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

SQL Server Join/where 处理顺序

在阅读了慢 SQL 查询后,不确定如何优化,这让我想到了查询的总体性能。当然,我们需要第一个表的结果(当其他表被连接时)在连接之前尽可能小(这个问题的内部连接),以使我们的查询更快一点。

例如,应该这样:

SELECT *
FROM   ( SELECT * FROM table1 WHERE col = @val ) t
INNER JOIN table2 ON col = col2
Run Code Online (Sandbox Code Playgroud)

比以下更好/更快:

SELECT *
FROM table1
INNER JOIN table2 ON col = col2
WHERE table1.col = @val
Run Code Online (Sandbox Code Playgroud)

我的理论如下(这可能不是正确的实现,我试图从我读过的 SQL Server 2008 内部书籍(MSFT Press)中记住):

  1. 查询处理器首先获取左表(table1)
  2. 连接第二个表 (table2) 并在过滤掉必要的行之前形成笛卡尔积(如果适用)
  3. 然后使用 SEELCT 语句最后执行 WHERE、ORDER BY、GROUP BY、HAVING 子句。

因此,如果在上面的语句 #1 中,表较小,则 SQL 引擎在形成笛卡尔积时要做的工作较少。然后,当您到达 where 语句时,您将拥有一个简化的结果集,可从中过滤内存。

我可能离目标太远了,这是不真实的。就像我说的,这是一个理论。

你的意见?

注意:我刚刚想到这个问题,还没有机会自己进行任何测试。

注2:标记为SQL Server的,因为我不知道任何关于MySQL等的实施,请随时接听/评论反正

performance join sql-server

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

安全地移动和创建新的 tempdb 文件

我想知道两件事:

  • 您如何以最少的停机时间安全地移动 tempdb?
  • 您需要多少个 tempdb 文件?

每个内核是 1 个文件吗?那么四核 = 4 个 tempdb 文件,创建三个新文件?

sql-server sql-server-2008-r2 tempdb

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

SQL Server 清单

继我的另一个问题之后,我想开始考虑每天/每周/每月应该在警报方面查看什么。我希望能够在问题发生之前看到问题(这就是计划)......

到目前为止,我已经开始收集以下脚本(无顺序):

日常的

  • 检查系统正常运行时间(以防万一我需要作为 DBA 检查任何内容)
  • 检查上次备份
  • 检查事务日志备份
  • 检查 SQL 作业的状态
  • 检查过去 24 小时(或 1140 分钟)的平均 CPU 使用率

每周

  • 检查 MSDB 备份历史记录
  • 检查上次运行 CheckDB 的时间
  • 检查索引碎片
  • 检查索引统计信息(读取与写入等)
  • 检查 IO 瓶颈

每月

  • 检查缺失的索引
  • 检查不再使用的索引

还有其他建议吗?(我是 DBA 的新手,所以任何帮助/建议总是受欢迎的)

sql-server-2005 sql-server-2008 maintenance

14
推荐指数
1
解决办法
7460
查看次数

与索引相关的 NOT 逻辑的使用

根据 Microsoft 的数据库开发书70-433:Microsoft SQL Server 2008 数据库开发

前导通配符和NOT逻辑都不允许查询优化器使用索引来优化搜索。为了获得最佳性能,您应该避免使用NOT关键字和前导通配符。

所以我认为那是NOT INNOT EXISTS等等

现在关于这个SO问题,我认为@GBN 选择的解决方案会违反上面给出的声明。

显然,事实并非如此。

所以我的问题是:为什么?

index sql-server optimization

13
推荐指数
1
解决办法
1789
查看次数

SQL-Server 中计算列的奇怪行为

在阅读我的 70-433 试卷时,我想到了一些我认为不起作用的东西,但我相信它确实有效。这段话是这样写的:

该列还必须标记为PERSISTED,这意味着 SQL Server 将计算列的表达式的结果物理存储在数据行中,而不是每次在查询中引用时计算它。

由此我明白了两件事:

  1. 非持续计算列计算每次它是在查询中引用时间
  2. 因为计算列没有存储任何内容,所以我假设不能为该列创建索引。

读完后,我觉得这有点奇怪,因为我在以前的项目中设法在非持久化列上创建了索引。

如何为未持久化的东西创建索引,从长远来看这是否有害?


为了证明这一点,我运行了以下 SQL 语句:

CREATE TABLE testTable
(
    ID INT IDENTITY(1,1) PRIMARY KEY,
    telephone VARCHAR(14),
    c_areaCode AS (SUBSTRING(telephone,0,5)),
    cp_areaCode AS (SUBSTRING(telephone,0,5)) PERSISTED
)

INSERT INTO testTable VALUES('09823 000000');
INSERT INTO testTable VALUES('09824 000000');
INSERT INTO testTable VALUES('09825 000000');

CREATE NONCLUSTERED INDEX IX_NotPersisted ON testTable(c_areaCode);
CREATE NONCLUSTERED INDEX IX_Persisted ON testTable(cp_areaCode);
Run Code Online (Sandbox Code Playgroud)

然后运行以下查询:

DBCC FREEPROCCACHE
DBCC FREESYSTEMCACHE('ALL');
DBCC DROPCLEANBUFFERS
GO
SELECT cp_areaCode FROM testTable;
GO
SELECT c_areaCode …
Run Code Online (Sandbox Code Playgroud)

sql-server

12
推荐指数
1
解决办法
1390
查看次数

关于 SARGability 的问题

我只需要确认我理解正确:

我最近查看了一个 SO 问题,其中用户在 Linq 中发布了一个答案,例如:

from p in db.table where p.column.AddMinutes(1) > DateTime.Now select p
Run Code Online (Sandbox Code Playgroud)

对于那些不熟悉 Linq 的人,我希望该语句的输出(未经公平测试)是:

SELECT *
FROM table t
WHERE DATEADD(min, 1, t.column) >= GETDATE() 
Run Code Online (Sandbox Code Playgroud)

我对此发表了回复,说日期时间操作应该在变量上(在这种情况下GETDATE()),因此实际上该语句应该反映如下内容:

SELECT *
FROM table t
WHERE t.column >= DATEADD(min, -1, GETDATE())
Run Code Online (Sandbox Code Playgroud)

在我的回复中,我现在不确定的部分,假设如下:

  1. 由于对列的操作,将不会使用索引
  2. 由于上述原因,查询计划将有所不同(未经测试,假设如此)
  3. 由于上述原因,第一个查询实际上会比第二个查询表现更差。

我的问题:

我在推理中遗漏了什么吗?我对么?最后,有没有机构有关于 SARGability 的好文章?

performance linq

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

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
查看次数

过度使用/正确使用模式?

Stackoverflow上问了这个问题后,我想知道我所做的是正确/最佳实践的地方。

基本上,我创建的每个对象都进入一个模式,模式名称反映了用法。例如,我有模式AuditAdmin(除其他外)。

这反过来在 中没有留下任何对象dbo。这个可以吗?还有什么我需要做的吗?

sql-server best-practices

10
推荐指数
2
解决办法
4093
查看次数