我刚刚了解到可以在表上禁用索引。甚至可以禁用聚集索引。此后,用户将无法访问索引或聚集索引中的数据。我们什么时候会禁用索引?我只是不明白用例。
每次在索引视图引用的基表中插入、更新或删除数据时,数据库引擎都会自动更新索引视图以反映更改。但是,我不太确定数据库引擎如何更新索引视图。它是否完全重新运行视图中的查询,或者是否使用更有效的方法仅更新相应的部分?
我正在学习 SQL Server 并试图了解 SQL Server 如何更新行。
据我了解,SQL Server首先对数据库加一个意向排它锁,然后对表加一个意向排它锁,然后对要更新的记录加一个更新锁。稍后,它将将该行上的更新锁转换为排他锁,以便可以修改该行中的数据。
但问题是共享锁与更新锁兼容。因此,虽然该行有更新锁,但其他会话仍然可以使用共享锁读取该行。如果行上有共享锁,则无法将更新锁转换为排它锁,因为共享锁和排它锁不兼容。
这是否意味着如果有会话连续读取该行,SQL Server 根本没有机会更新该行。这种情况可能会持续很长一段时间。这是真的?SQL Server 会等到该行上没有共享锁时才开始更新其中的数据吗?
我所说的“连续”是指一个会话读取该行,并且在从该行释放共享锁之前,另一个会话在同一行上放置一个共享锁。在第二个共享锁从该行释放之前,另一个会话在同一行上放置另一个共享锁,依此类推。因此,基本上,该行上总是至少有一个共享锁。
为什么下面的批次不能按预期工作?
DROP TABLE IF EXISTS #test1;
IF 1 = 1
SELECT *
INTO #test1
FROM sys.databases
WHERE database_id <= 5;
ELSE
SELECT *
INTO #test1
FROM sys.databases;
SELECT *
FROM #test1;
Run Code Online (Sandbox Code Playgroud)
当我运行它时,我得到:
消息 2714,级别 16,状态 1,第 12 行 数据库中已有一个名为“#test1”的对象。
我必须像这样更改代码:
DROP TABLE IF EXISTS ##test1;
IF 1 = 1
EXEC ('
SELECT *
INTO ##test1
FROM sys.databases
WHERE database_id <= 5;
' );
ELSE
EXEC ('
SELECT *
INTO ##test1
FROM sys.databases;');
SELECT *
FROM ##test1;
Run Code Online (Sandbox Code Playgroud)
这按预期工作。上述错误似乎是一个解析错误,我不确定。谁能帮忙解释一下这里发生了什么?
我试图了解 SQL Server 版本存储和相关的隔离级别。据我了解,当数据库启用读取已提交快照选项时,可能会发生这种情况:
update products set price = price * 1.5。由于这涉及表的所有行,因此需要很长时间。update语句仍在进行时,会话 2 启动一个查询:select * from products where id = 1。由于数据库处于读已提交快照模式,因此写入者不会阻止读取者。因此,会话 1 从版本存储中读取该行的旧版本,并认为该产品的价格为 1000 美元。update语句执行完毕,产品(id = 1)的新价格为 1500 美元。如果用户知道产品的新价格,他就不会购买。在这种情况下,会发生什么呢?这种情况实际上可能吗?如果是这样,防止这种情况的规范是什么?
sql-server isolation-level tempdb-version-store snapshot-isolation
DECLARE @key INTEGER = 33, @val INTEGER = 44;
BEGIN TRANSACTION;
INSERT dbo.t([key], val)
SELECT @key, @val
WHERE NOT EXISTS
(
SELECT 1 FROM dbo.t WITH (UPDLOCK, SERIALIZABLE)
WHERE [key] = @key
);
IF @@ROWCOUNT = 0
BEGIN
UPDATE dbo.t SET val = @val WHERE [key] = @key;
END
COMMIT TRANSACTION;
Run Code Online (Sandbox Code Playgroud)
DECLARE @key INTEGER = 33, @val INTEGER = 44;
BEGIN TRANSACTION;
INSERT dbo.t WITH (UPDLOCK, SERIALIZABLE) ([key], val)
SELECT @key, @val
WHERE NOT EXISTS
(
SELECT 1 …Run Code Online (Sandbox Code Playgroud) 今天我正在阅读一些很久以前做的数据库笔记。我看到了这个查询:
UPDATE Sales.Orders
SET (shipcountry, shipregion, shipcity)=
(SELECT country, region, city
FROM Sales.Customers AS C
WHERE C.custid =Sales.Orders.custid)
WHERE custid IN
(SELECT custid FROM Sales.Customers WHERE country = 'USA');
Run Code Online (Sandbox Code Playgroud)
我对这个语法真的很陌生。但我的注释说它是“有效的 SQL Server 更新语法”。这是真的?SSMS 无法解析它。当我尝试运行它时,我得到了这个:
另外,SQL Server 的UPDATE文档似乎建议在关键字(之后不允许使用SET。无论如何,我只是想确认一下。
我已经使用 SQL Server Management Studio (SSMS) 一段时间了,但是有没有办法使用键盘快捷键快速切换到右侧或左侧编辑器选项卡?目前,我必须使用鼠标在选项卡之间切换,这可能有点耗时。
在 SSMS 中的选项卡之间切换的键盘快捷键(如果有的话)是什么?或者有其他方法可以更有效地做到这一点吗?
此外,我注意到,当我打开多个选项卡时,SSMS 会移动编辑器而不是切换到它们(例如,单击“窗口”-“Windows”,然后双击一个条目),这可能有点令人困惑。我想了解这种行为背后的逻辑,以及是否有一种方法可以在选项卡之间切换而无需编辑器四处移动。
我是公司数据库团队的一员,目前面临查询优化和性能方面的困境。每当我的一些同事遇到查询速度慢时,他们的默认解决方案就是创建索引来加快查询速度。这导致一些表有超过 70 个索引!
就我个人而言,我倾向于以不同的方式处理这个问题。我经常发现自己修改现有索引(例如添加额外的包含列等)以加快查询速度,而不是每次都创建新索引。然而,并非所有团队成员都采用这种方法,导致我们数据库中的索引数量不断增加。
尽管做出了这些努力,我还是注意到,随着索引数量的增加,其他 DML 操作的速度有所减慢。这似乎是一个第二十二条军规:没有索引,查询会很慢,但是有了索引,其他一切都会变慢一点。
我正在寻求有关如何应对这种情况的建议。有多少索引通常被认为“太多”?是否有任何最佳实践或策略来平衡快速查询的需求与整体数据库性能?
任何见解或资源将不胜感激。
谢谢你!
我有一个关于大型数据库上的透明数据加密 (TDE) 的问题。当数据库启用 TDE 时,我可以继续访问它吗?具体来说,我可以对数据库执行 SELECT、INSERT 和 UPDATE 操作吗?
我了解 TDE 会加密静态数据,但我不确定这是否会影响加密过程发生时访问数据的能力。我非常感谢那些有 TDE 经验的人提供的任何见解或建议。
先感谢您!
sql-server ×10
index ×2
t-sql ×2
update ×2
blocking ×1
errors ×1
hints ×1
index-tuning ×1
locking ×1
performance ×1
ssms ×1
syntax ×1
transparent-data-encryption ×1
upsert ×1