nvarchar问题上的SQL Server唯一索引

时间:2014-05-01 22:04:18

标签: sql sql-server nvarchar unique-index

我有一个带有nvarchar(50)列的SQL Server表。此列必须是唯一的,并且不能是PK,因为另一列是PK。所以我在这个列上设置了一个非聚集的唯一索引。

在可序列化事务中的大量insert语句中,我想在不同的事务中仅基于此列执行select查询。但这些插件似乎锁定了桌子。例如,如果我将unique列的数据类型更改为bigint,则不会发生锁定。

为什么nvarchar不工作,而bigint呢?如何使用nvarchar(50)作为数据类型来实现相同的目标?

3 个答案:

答案 0 :(得分:2)

毕竟,神秘解决了!相当愚蠢的情况,我猜..

问题出在select语句中。 where子句缺少引号,但是由于现有数据的错误巧合只是数字,所以选择没有失败,但只是在插入提交之前没有执行。插入第一个字母数字数据后,选择语句开始失败,并且错误地将数据类型nvarchar转换为数字'

e.g 而不是

SELECT [my_nvarchar_column]  
FROM [dbo].[my_table]  
WHERE [my_nvarchar_column] = '12345'

select语句是

SELECT [my_nvarchar_column]  
FROM [dbo].[my_table]  
WHERE [my_nvarchar_column] = 12345

我想进行了一次无声演员表演,没有使用唯一的索引导致该块。 修正了声明,现在一切正常。

感谢大家的帮助,对这个相当愚蠢的问题感到抱歉!

答案 1 :(得分:1)

首先,您可以将PK更改为非聚集索引,然后您可以在此字段上创建聚簇索引。当然,根据您的使用情况,这可能是一个坏主意,或者只是没有帮助。

您可能有覆盖索引的用例,请参阅上一页question re: covering index

您可以更改其他查询"通过更改这些查询的隔离级别来实现非阻塞。

在单个事务中插入大量行是必要的。您可以简单地不使用事务,或者拆分成较小的事务集以避免锁定表的大部分。例如,您可以将记录插入到事务中的挂起表(在正常活动中未使用),然后如果不需要实时发布到主表,则将较小事务中的这些记录迁移到主表。 / p>

ADDED

也许是最明显的问题。您确定必须使用可序列化的事务来插入大量记录吗?在金融交易之外,这些相对很少是必要的,与其他隔离级别相比,它们的并发成本较高?

ADDED

根据您关于"全部或没有"的评论,您描述的是原子性,而不是可序列化。也就是说,您可以为大型插入事务使用不同的隔离级别,并且仍然具有原子性。

第二件事,我注意到你指定了大量的insert语句。这听起来好像您应该能够将这些插入推送到挂起/临时表中,然后从登台表执行单个插入或批量插入到生产表中。是的,这是更多的工作,但你可能只是有一个需要额外努力的现有问题。

答案 2 :(得分:0)

您可能希望将NOLOCK提示(a.k.a. READUNCOMMITTED)添加到您的查询中。它将允许对已经插入的数据执行“脏读”。

e.g。

SELECT [my_nvarchar_column] FROM [dbo].[locked_table] WITH (NOLOCK)

在这里看一个更好的解释:

http://www.mssqltips.com/sqlservertip/2470/understanding-the-sql-server-nolock-hint/

这里的READUNCOMMITTED部分:

http://technet.microsoft.com/en-us/library/ms187373.aspx