我的许多数据库都有定义为 varchars 的字段。自从我在美国生活和工作以来,这并不是什么大问题(那里唯一存在的语言是“美国”。咳咳)
在使用数据库大约 5 年后,我发现我最终遇到了 varchar 字段的有限性质的问题,我必须修改我的字段以将数据存储为 nvarchars。在不得不对表进行另一次更新,将 varchar 字段转换为 nvarchar 之后,我有了一个想法——为什么我们仍然这样做?我早就决定将所有新的文本字段定义为 nvarchar,而不是 varchar,这是我 10 年前在学校时从教科书中学到的。
现在是 2011 年,去年发布了新版本的 SQL Server。当我们可以/应该使用 nvarchar 时,为什么我们继续支持 varchar 数据类型?
我知道经常有人争论 nvarchars 是 varchars 的“两倍大”,因此存储空间的使用可能是维护 varcars 的一个争论点。
但是,今天的用户如果想节省存储空间,可以定义他们的 nvarchars 以将数据存储为 UTF-8 而不是默认的 UTF-16。如果主要需要,这将允许 8 位编码,同时保证插入到他们的数据库中的稀有 2-8 字节字符不会破坏任何东西。
我错过了什么吗?在过去的 15 到 20 年里,这是否有充分的理由没有改变?
sql-server-2008 database-design sql-server sql-server-2008-r2
将 SQL Server 和 Management Studio 从 2008 升级到 2012 后,Management Studio 2012 在打开新查询窗口和对话框时非常慢。
即使右键单击表格也很慢。在我开始在窗口内做任何事情之前,通常至少有 5 秒的延迟。每次都会发生这种情况,即使我连续两次打开同一个窗口。为什么会发生这种情况,我该如何解决?
其他应用程序非常快速地建立与数据库的连接。
我尝试过但没有帮助的事情:
hosts文件我的电脑应该足够快了,而且我还有 16GB 内存。我的硬件绝对不应该有问题。看起来 SSMS 正在等待某些东西 - 在发生这种情况时,我可以顺利运行其他程序。
我没有机会安装 SQL Server 2012 CU1 更新,因为安装修补程序似乎存在一些错误风险,我现在不能冒险。
对于我尝试优化的中等复杂查询,我注意到删除TOP n子句会更改执行计划。我猜想,当查询包含TOP n数据库引擎时,会运行查询而忽略该TOP子句,然后最后将结果集缩小到请求的n行数。图形执行计划似乎表明情况确实如此——TOP是“最后”一步。但似乎还有更多事情发生。
我的问题是,TOP n 子句如何(以及为什么)影响查询的执行计划?
这是我的情况的简化版本:
查询匹配来自两个表 A 和 B 的行。
如果没有该TOP子句,优化器估计将有来自表 A 的 19k 行和来自表 B 的 46k 行。返回的实际行数是 A 的 16k 和 B 的 13k。哈希匹配用于连接这两个结果集总共 69 行(然后应用排序)。此查询发生得非常快。
当我添加TOP 1001优化器时不使用哈希匹配;相反,它首先对表 A 的结果进行排序(与 19k/16k 相同的估计值/实际值)并对表 B 执行嵌套循环。表 B 的估计行数现在为 1,奇怪的是TOP n直接影响对 B 的估计执行次数(索引搜索) - 它似乎总是2n+1,或者在我的情况下是 2003 年。如果我改变,这个估计会相应地改变TOP n。当然,由于这是嵌套连接,因此实际执行次数为 16k(表 A 中的行数),这会减慢查询速度。
实际场景有点复杂,但这捕获了基本思想/行为。两个表都使用索引查找进行搜索。这是 SQL Server 2008 R2 企业版。
performance sql-server optimization execution-plan query-performance
我试图更好地了解DELETE和TRUNCATE命令之间的差异。我对内部结构的理解大致如下:
DELETE-> 数据库引擎从相关数据页和输入该行的所有索引页中查找并删除该行。因此,索引越多,删除所需的时间就越长。
TRUNCATE -> 简单地删除所有表的数据页,使其成为删除表内容的更有效选项。
假设以上是正确的(如果不正确,请纠正我):
我正在尝试使用索引来加快速度,但是在连接的情况下,索引并没有改善查询执行时间,并且在某些情况下它会减慢速度。
创建测试表并用数据填充它的查询是:
CREATE TABLE [dbo].[IndexTestTable](
[id] [int] IDENTITY(1,1) PRIMARY KEY,
[Name] [nvarchar](20) NULL,
[val1] [bigint] NULL,
[val2] [bigint] NULL)
DECLARE @counter INT;
SET @counter = 1;
WHILE @counter < 500000
BEGIN
INSERT INTO IndexTestTable
(
-- id -- this column value is auto-generated
NAME,
val1,
val2
)
VALUES
(
'Name' + CAST((@counter % 100) AS NVARCHAR),
RAND() * 10000,
RAND() * 20000
);
SET @counter = @counter + 1;
END
-- Index in question
CREATE NONCLUSTERED INDEX [IndexA] ON [dbo].[IndexTestTable] …Run Code Online (Sandbox Code Playgroud) 这个问题在这里以各种形式提出,但问题归结为:
我知道缩小数据库是有风险的。在这种情况下,我已经删除了这么多数据,我再也不会使用它了。
如果我有一个UPDATE实际上没有改变任何数据的语句(因为数据已经处于更新状态)。在WHERE子句中进行检查以防止更新是否有任何性能优势?
例如,以下 UPDATE 1 和 UPDATE 2 之间的执行速度是否有任何差异:
CREATE TABLE MyTable (ID int PRIMARY KEY, Value int);
INSERT INTO MyTable (ID, Value)
VALUES
(1, 1),
(2, 2),
(3, 3);
-- UPDATE 1
UPDATE MyTable
SET
Value = 2
WHERE
ID = 2
AND Value <> 2;
SELECT @@ROWCOUNT;
-- UPDATE 2
UPDATE MyTable
SET
Value = 2
WHERE
ID = 2;
SELECT @@ROWCOUNT;
DROP TABLE MyTable;
Run Code Online (Sandbox Code Playgroud)
我问的原因是我需要行数来包含未更改的行,所以我知道如果 ID 不存在是否进行插入。因此,我使用了 UPDATE 2 表单。如果使用 UPDATE 1 表单有性能优势,是否有可能以某种方式获得我需要的行数?
我们希望停用一个 SQL Server 实例,该实例上仍保留有几个数据库。
如何判断用户或 Web 应用程序是否仍在使用它们?
我找到了一个论坛帖子,里面有一个 T-SQL 查询,你可以运行它来检索上次查询日期。它似乎有效,但我想知道此信息是否足够有效以删除数据库。是吗?
如果您有其他方法也有帮助。
我不得不处理的最令人困惑的问题之一与存储过程组有关。给定一个存储过程 ,usp_DoSomethingAwesome我可以通过调用它在另一个组中创建该过程usp_DoSomethingAwesome;2。
我在解决一些由系统生成的插入、更新和删除复制存储过程引起的复制问题(发布者:SQL 2000 Ent.,Dist/Sub:2008 R2 Ent.)时发现了这一点。
拥有这种“分组”能力的目的/想法是什么?
我想我曾经在某处读到过写入 tempdb 比不在 tempdb 中的实际表更快。这在任何情况下都是真的吗?我想我记得它说了一些关于 tempdb 并将数据存储在内存中的特殊内容?
sql-server ×10
performance ×2
index ×1
memory ×1
optimization ×1
shrink ×1
ssms ×1
t-sql ×1
tempdb ×1
update ×1