在为我之前问的另一个问题创建测试数据库时,我记得可以声明主键 NONCLUSTERED
什么时候使用NONCLUSTERED主键而不是CLUSTERED主键?
提前致谢
我试图更好地了解DELETE和TRUNCATE命令之间的差异。我对内部结构的理解大致如下:
DELETE-> 数据库引擎从相关数据页和输入该行的所有索引页中查找并删除该行。因此,索引越多,删除所需的时间就越长。
TRUNCATE -> 简单地删除所有表的数据页,使其成为删除表内容的更有效选项。
假设以上是正确的(如果不正确,请纠正我):
在阅读了慢 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 中,表较小,则 SQL 引擎在形成笛卡尔积时要做的工作较少。然后,当您到达 where 语句时,您将拥有一个简化的结果集,可从中过滤内存。
我可能离目标太远了,这是不真实的。就像我说的,这是一个理论。
你的意见?
注意:我刚刚想到这个问题,还没有机会自己进行任何测试。
注2:标记为SQL Server的,因为我不知道任何关于MySQL等的实施,请随时接听/评论反正
我想知道两件事:
每个内核是 1 个文件吗?那么四核 = 4 个 tempdb 文件,创建三个新文件?
继我的另一个问题之后,我想开始考虑每天/每周/每月应该在警报方面查看什么。我希望能够在问题发生之前看到问题(这就是计划)......
到目前为止,我已经开始收集以下脚本(无顺序):
日常的
每周
每月
还有其他建议吗?(我是 DBA 的新手,所以任何帮助/建议总是受欢迎的)
根据 Microsoft 的数据库开发书70-433:Microsoft SQL Server 2008 数据库开发:
前导通配符和NOT逻辑都不允许查询优化器使用索引来优化搜索。为了获得最佳性能,您应该避免使用NOT关键字和前导通配符。
所以我认为那是NOT IN,NOT EXISTS等等
现在关于这个SO问题,我认为@GBN 选择的解决方案会违反上面给出的声明。
显然,事实并非如此。
所以我的问题是:为什么?
在阅读我的 70-433 试卷时,我想到了一些我认为不起作用的东西,但我相信它确实有效。这段话是这样写的:
该列还必须标记为PERSISTED,这意味着 SQL Server 将计算列的表达式的结果物理存储在数据行中,而不是每次在查询中引用时计算它。
由此我明白了两件事:
读完后,我觉得这有点奇怪,因为我在以前的项目中设法在非持久化列上创建了索引。
如何为未持久化的东西创建索引,从长远来看这是否有害?
为了证明这一点,我运行了以下 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) 我只需要确认我理解正确:
我最近查看了一个 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)
在我的回复中,我现在不确定的部分,假设如下:
我的问题:
我在推理中遗漏了什么吗?我对么?最后,有没有机构有关于 SARGability 的好文章?
我有一个这样的查询:
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 是否为整个查询计算一次值?
在Stackoverflow上问了这个问题后,我想知道我所做的是正确/最佳实践的地方。
基本上,我创建的每个对象都进入一个模式,模式名称反映了用法。例如,我有模式Audit和Admin(除其他外)。
这反过来在 中没有留下任何对象dbo。这个可以吗?还有什么我需要做的吗?
sql-server ×8
optimization ×2
performance ×2
index ×1
join ×1
linq ×1
maintenance ×1
primary-key ×1
tempdb ×1