标签 SQL Server 下的文章

各版本SQL Server的新功能


SQL Server 2005

  • CLR 集成:支持 .NET 代码在数据库内运行。
  • XML 数据类型:原生支持 XML 数据存储与查询。
  • 分区表/索引:提升大型表的管理和查询性能。
  • 数据库镜像:高可用性解决方案。
  • TRY-CATCH 错误处理:增强 T-SQL 错误处理能力。
  • 排名函数(ROW_NUMBER, RANK 等)。
  • Service Broker:异步消息处理框架。

SQL Server 2008

  • 数据压缩:减少存储空间并提升 I/O 性能。
  • 透明数据加密(TDE):数据库文件级加密。
  • 策略管理(基于策略的管理)。
  • CDC(变更数据捕获):跟踪数据变更。
  • Filestream:将非结构化数据存储在文件系统中。
  • 空间数据类型(GEOGRAPHY, GEOMETRY)。

SQL Server 2012

  • 列存储索引:大幅提升数据仓库查询性能。
  • AlwaysOn 可用性组:替代数据库镜像的高可用方案。
  • 序列对象(SEQUENCE)。
  • 分页增强(OFFSET-FETCH)。
  • 包含数据库:部分数据库独立性。
  • 文件表(FileTable):基于 Filestream 的文件管理。

SQL Server 2014

  • 内存优化表(In-Memory OLTP):基于 Hekaton 引擎。
  • 更新聚集列存储索引(可更新)。
  • SSD 缓冲池扩展:将缓冲池扩展到 SSD。
  • Azure 集成增强:备份到 Azure 等。
  • 资源调控器增强:支持 I/O 控制。

SQL Server 2016

  • JSON 支持:原生 JSON 解析与生成。
  • PolyBase:查询 Hadoop 或 Azure Blob 数据。
  • 实时查询统计(Live Query Statistics)。
  • 动态数据掩码(Dynamic Data Masking)。
  • 行级安全性(Row-Level Security)。
  • 时态表(Temporal Tables):自动历史数据跟踪。
  • Stretch Database:将冷数据扩展至 Azure。

SQL Server 2017

  • Linux 支持:首次支持 Linux 系统。
  • Python 集成:机器学习和分析服务支持 Python。
  • 自适应查询处理:优化查询执行计划。
  • 自动数据库优化(Automatic Tuning)。
  • 图形数据库功能:支持节点和边表结构。

SQL Server 2019

  • 大数据群集:集成 Spark 与 HDFS。
  • 智能查询处理(Intelligent Query Processing)。
  • 数据虚拟化:通过 PolyBase 连接更多数据源。
  • Java 语言扩展:支持 Java 代码运行。
  • 加速数据库恢复(Accelerated Database Recovery)。
  • UTF-8 编码支持

SQL Server 2022

  • Azure 无缝集成:与 Azure Synapse、Purview 深度集成。
  • 参数敏感计划优化(Parameter-Sensitive Plan Optimization)。
  • 边缘计算支持(Edge 版本)。
  • 多写入副本(最多 4 个同步副本)。
  • 内置数据分类与发现
  • Parquet 格式支持:通过 PolyBase 读写 Parquet 文件。

原因在于每个扇区的物理字节数。

使用以下命令可以查看:

fsutil fsinfo sectorinfo c:
LogicalBytesPerSector :                                 512
PhysicalBytesPerSectorForAtomicity :                    32768
PhysicalBytesPerSectorForPerformance :                  32768
FileSystemEffectivePhysicalBytesPerSectorForAtomicity : 4096
设备校准 :                                        已校准(0x000)
设备上的分区校准:                                  已校准(0x000)
无搜寻惩罚
支持剪裁
不支持 DAX
未精简预配

这两个32768是导致sqlserver出错的原因。
解决方案就是执行以下命令:

reg add "HKLM\SYSTEM\CurrentControlSet\Services\stornvme\Parameters\Device" /v "ForcedPhysicalSectorSizeInBytes" /t reg_multi_sz /d "* 4095" /f

重启之后再查看结果:

LogicalBytesPerSector :                                 512
PhysicalBytesPerSectorForAtomicity :                    4096
PhysicalBytesPerSectorForPerformance :                  4096
FileSystemEffectivePhysicalBytesPerSectorForAtomicity : 4096
设备校准 :                                        已校准(0x000)
设备上的分区校准:                                  已校准(0x000)
无搜寻惩罚
支持剪裁
不支持 DAX
未精简预配

详情

取消默认可查看任何数据库

DENY VIEW any DATABASE TO PUBLIC;

赋予自己拥有管理权限的数据库的查看权限

ALTER AUTHORIZATION ON DATABASE::[Database] TO [User];

注意:
如果数据库已存在用户权限,则可能要删除后再操作

如果需要该用户可以使用SQL Profiler来跟踪SQL,则需要执行:

GRANT ALTER TRACE TO [USER]

注意:
此命令将使该用户跟踪所有SQL,包括未授权的数据库。

共享锁 (Shared Lock):

表示一个事务正在读取一行数据,其他事务也可以读取同一行数据,但不能进行写操作。
也称为 "S锁" 或 "读锁"。

典型应用场景:当一个事务需要读取数据而不修改它时,可以使用共享锁。多个事务可以同时获取共享锁,并且彼此之间不会产生冲突。
-- 在事务中获取共享锁
BEGIN TRANSACTION;
SELECT * FROM table_name WITH (TABLOCKX, HOLDLOCK) WHERE column_name = 'value';
-- 其他事务可以读取同一行的数据,但不能进行写操作
COMMIT;

排他锁 (Exclusive Lock):

表示一个事务正在对一行数据进行写操作,并阻止其他事务对同一行进行读或写操作。
也称为 "X锁" 或 "写锁"。

典型应用场景:当一个事务需要对数据进行修改或删除操作时,可以使用排他锁。该锁会阻止其他事务对同一行进行读取或写入,确保数据的一致性。
-- 在事务中获取排他锁
BEGIN TRANSACTION;
SELECT * FROM table_name WITH (XLOCK) WHERE column_name = 'value';
-- 其他事务无法读取或写入同一行的数据
COMMIT;

更新锁 (Update Lock):

用于实现读取操作和避免并发更新冲突的特殊锁定模式。当一个事务使用更新锁时,其他事务也可以读取同一行数据,但不能进行写操作。
更新锁是共享锁和排他锁之间的折衷选择。
也称为 "U锁" 或 "升级锁"。

典型应用场景:在读取数据时,如果事务预计可能在稍后需要对数据进行更新操作,但目前仅需要共享访问权限,可以使用更新锁。这样可以避免读取和更新之间的竞争条件,提高并发性。
-- 在事务中获取更新锁
BEGIN TRANSACTION;
SELECT * FROM table_name WITH (UPDLOCK) WHERE column_name = 'value';
-- 其他事务可以读取同一行的数据,但不能进行写操作
COMMIT;

表锁 (Table Lock):

锁定整个表,阻止其他事务对该表的读或写操作。
表级锁可能对并发性产生较大影响,因为它限制了其他事务对表的访问。

典型应用场景:当需要对整个表进行大规模的操作,如数据重建、表结构修改等,可以使用表锁。这会阻止其他事务对表进行读取或写入操作,确保操作的完整性。
-- 在事务中获取表锁
BEGIN TRANSACTION;
SELECT * FROM table_name WITH (TABLOCKX) WHERE column_name = 'value';
-- 其他事务无法读取或写入整个表
COMMIT;

页级锁 (Page Lock):

锁定表的数据页,即一组相邻的数据行。
页级锁通常用于较大的事务或特定的锁定提示。

典型应用场景:在某些情况下,表中的数据按页组织,而不是按行组织。当需要访问特定数据页时,可以使用页级锁。这可以减少锁的粒度,提高并发性能。
-- 在事务中获取页级锁
BEGIN TRANSACTION;
SELECT * FROM table_name WITH (PAGLOCK) WHERE column_name = 'value';
-- 其他事务无法读取或写入同一数据页的数据
COMMIT;

行级锁 (Row Lock):

锁定表的单个数据行。
行级锁提供了最细粒度的并发控制,但也可能导致更多的锁开销和资源争用。

典型应用场景:当需要对表中的特定行进行操作时,可以使用行级锁。这允许并发事务对不同行进行读取和写入操作,提高并发性能。
-- 在事务中获取行级锁
BEGIN TRANSACTION;
SELECT * FROM table_name WITH (ROWLOCK) WHERE column_name = 'value';
-- 其他事务无法读取或写入同一行的数据
COMMIT;

此外,还存在其他一些重要的锁类型,包括:

键值锁 (Key-Range Lock):

锁定表中的一定范围的键值,通常与范围查询和索引操作相关。
键值锁用于防止并发操作引起的范围扫描和索引不一致性。

典型应用场景:当进行范围查询或索引操作时,可以使用键值锁。它可以锁定一定范围的键值,以确保范围扫描的一致性。
-- 在事务中获取键值锁
BEGIN TRANSACTION;
SELECT * FROM table_name WITH (XLOCK) WHERE column_name BETWEEN 'value1' AND 'value2';
-- 其他事务无法读取或写入指定键值范围内的数据
COMMIT;

意向锁 (Intent Lock):

用于指示一个事务已经在某一级别上持有锁,以阻止其他事务对更精细级别的锁定进行操作。
意向锁包括意向共享锁 (IS) 和意向排他锁 (IX)。

典型应用场景:意向锁用于指示事务在特定级别上持有锁,以避免其他事务获取冲突的更细粒度锁。它通常与其他锁类型结合使用。
-- 在事务中获取意向锁
BEGIN TRANSACTION;
SELECT * FROM table_name WITH (IS) WHERE column_name = 'value';
-- 其他事务无法获取排他锁(X锁)
COMMIT;

共享更新锁 (Shared Update Lock):

允许多个事务同时获取对同一数据行的共享更新锁,以支持并发读取和更新操作。

典型应用场景:当多个事务需要同时读取并更新同一数据行时,可以使用共享更新锁。这允许多个事务同时获取对同一数据行的共享更新锁,以支持并发读取和更新操作。
-- 在事务中获取共享更新锁
BEGIN TRANSACTION;
SELECT * FROM table_name WITH (SIXU) WHERE column_name = 'value';
-- 允许多个事务同时获取对同一数据行的共享更新锁,支持并发读取和更新操作
COMMIT;

这些是 SQL Server 中的一些常见和重要的锁类型,用于控制并发性和维护数据完整性。在设计和优化数据库应用程序时,了解不同类型的锁以及它们的行为和影响是至关重要的。

上述9种锁的横向对比:
锁类型 并发性 锁定粒度 锁定范围 冲突 适用场景
共享锁 (Shared Lock) 高 行级 仅限读 读冲突 并发读取,不修改数据
排他锁 (Exclusive Lock) 低 行级 整个行 读写冲突 数据修改,防止其他事务读取或写入同一行数据
更新锁 (Update Lock) 中 行级 仅限读 写冲突 并发读取,预计稍后可能需要对数据进行更新
表锁 (Table Lock) 低 表级 整个表 读写冲突 大规模操作,如数据重建、表结构修改等
页级锁 (Page Lock) 中 页级 数据页 读写冲突 针对按页组织的数据,减少锁的粒度以提高并发性能
行级锁 (Row Lock) 高 行级 单个数据行 读写冲突 针对特定行的读写操作
键值锁 (Key-Range Lock) 中 键值范围 指定键值范围 读写冲突 范围查询或索引操作
意向锁 (Intent Lock) - 数据结构级 整个数据结构 冲突解决 协调低层次锁定请求的锁
共享更新锁 (Shared Update Lock) 高 行级 单个数据行 读冲突 并发读取和更新同一行

注意:表格中的并发性指的是该锁对并发读写操作的支持程度,高表示较好的并发性能,低表示较差的并发性能。锁定粒度指的是锁定的对象粒度,可以是行、页或表级别。锁定范围指的是锁定的数据范围,可以是单个行、整个表或键值范围等。冲突表示该锁类型与其他锁类型之间可能发生的冲突。适用场景指的是每种锁类型常见的使用场景。

请注意,锁的选择取决于具体的业务需求和并发控制策略。在实际应用中,需要根据具体情况选择适当的锁

在SQL Server中,有几种不同的排他锁类型。以下是常见的排它锁:

  • XLOCK:
    XLOCK 是一种行级排它锁,用于阻止其他事务对同一行数据进行读取或写入操作。
    当一个事务使用 XLOCK 锁定一行数据时,其他事务无法同时读取或写入相同的数据行。
  • TABLOCKX:
    TABLOCKX 是一种表级排它锁,用于阻止其他事务对整个表进行读取或写入操作。
    当一个事务使用 TABLOCKX 锁定一张表时,其他事务无法同时读取或写入相同的表。
  • HOLDLOCK:
    HOLDLOCK 是一种保持锁的提示,用于在整个事务期间保持排它锁。
    当一个事务使用 HOLDLOCK 提示时,它会保持已经获取的锁,直到事务结束。
  • UPDLOCK:
    UPDLOCK 是一种特殊的锁定提示,用于实现读取操作和避免并发更新冲突。
    当一个事务使用 UPDLOCK 提示时,其他事务可以读取相同的数据行,但不能对其进行写操作。
    这些排它锁类型可以根据具体的业务需求和并发控制策略进行选择和使用。它们提供了不同的锁定粒度和锁定范围,用于控制对数据的访问和修改。需要注意的是,在使用排它锁时,应注意锁的粒度和范围,避免过度锁定导致并发性能下降。

TABLOCKX 和 XLOCK在功能和使用上的区别:

  • TABLOCKX:

    • TABLOCKX 是一种表级排他锁,用于阻止其他事务对整个表进行读取或写入操作。
    • 当一个事务使用 TABLOCKX 提示时,其他事务无法同时读取或写入相同的表。
    • TABLOCKX 是一种较强制的锁定方式,它会阻止其他事务对整个表的任何访问,包括读取和写入操作。
    • TABLOCKX 通常在需要对整个表进行大规模修改或操作时使用,例如数据重建、表重命名等。
  • XLOCK:

    • XLOCK 是一种行级排他锁,用于阻止其他事务对同一行数据进行读取或写入操作。
    • 当一个事务使用 XLOCK 提示时,其他事务无法同时读取或写入相同的数据行。
    • XLOCK 是一种较强制的锁定方式,它会阻止其他事务对同一行数据的任何访问,包括读取和写入操作。
    • XLOCK 通常在需要对特定行进行修改或操作时使用,例如数据更新、删除等。

总结来说,TABLOCKX 是一种表级排他锁,阻止其他事务对整个表进行访问,而 XLOCK 是一种行级排他锁,阻止其他事务对特定行数据进行访问。选择使用哪种锁取决于具体的业务需求和并发控制策略。需要注意的是,过度使用强制性的锁定提示可能会导致并发性能下降,因此应该谨慎使用。

来源: Ceri的Blog
参考: MSDN