char列上的MAX/ORDER BY

Tim*_*ter 1 sql-server performance database-design sql-server-2005 sql-order-by

在我的SQL Server 2005数据库中,我RMA_Number在表中有一个数据类型为char(10)的列RMA.

该值随着格式的增加而增加RMA0002511.在插入时增加最高数字的最快方法是什么?

我的第一个方法是:

SELECT     TOP (1) RMA_Number
FROM         RMA
WHERE     (RMA_generated = 1)
ORDER BY Creation_Date DESC
Run Code Online (Sandbox Code Playgroud)

但这很容易出错,因为某种程度上可能更高的RMA_Number具有更早的创建日期.作为解决方法,按主键排序有效:

SELECT     TOP (1) RMA_Number
FROM         RMA
WHERE     (RMA_generated = 1)
ORDER BY idRMA DESC
Run Code Online (Sandbox Code Playgroud)

但也许这也是一个可能的错误来源.

从逻辑上讲,最好的方法是ORDER BY RMA_Number DESC.

但是因为我不确定这是否总能提供正确的结果,并认为如果记录数增加,排序char列会变慢,我选择按Date列排序.

所以,

  1. 通过char(10)-column(性能和准确度)进行排序是个好主意?
  2. SELECT MAX( RMA_Number ) FROM RMA得到最高数字(性能和准确性)会更好吗
  3. 如果前两个点错误,或者我应该使用int列并在应用程序中格式化数字,我应该坚持使用主键来排序吗?

编辑:

我想我必须澄清一些我没有提到过的事情.每次插入时都不会生成RMA_Number.所以也许有很多没有数字的记录.Martin使用主键来构建数字.这将是一个问题,因为差距太大.

先感谢您.

Mar*_*ith 7

最快和最安全(并发)方式是根本不存储RMA000...前缀.

只需创建一个整数标识列,并通过计算列添加前缀.

create table #RMA
(
id int identity(2511,1) primary key,
RMA_Number as 'RMA' + RIGHT('000000' + CAST(id as varchar(7)),7)
)

insert into #RMA
default values

select * from #RMA
Run Code Online (Sandbox Code Playgroud)

或者,根据并非所有记录都有的新信息,RMA_Number您可以将此方法用于非阻塞,高效且并发的安全解决方案.

CREATE TABLE dbo.Sequence(
 val int IDENTITY (2511, 2) /*Seed this at 1 + whatever your current max value is*/
 )

GO

/*Call this procedure to get allocated the next sequence number to use*/     
CREATE PROC dbo.GetSequence
@val AS int OUTPUT
AS
BEGIN TRAN
    SAVE TRAN S1
    INSERT INTO dbo.Sequence DEFAULT VALUES
    SET @val=SCOPE_IDENTITY()
    ROLLBACK TRAN S1 /*Rolls back just as far as the save point to prevent the 
                       sequence table filling up. The id allocated won't be reused*/
COMMIT TRAN
Run Code Online (Sandbox Code Playgroud)

  • @Brad.是int比较比字符串快.如果它被索引,那么这个成本可能是在插入时支付而不是查找时间(至少对于找到'max`值的特定情况).使用身份也比自制的并发安全解决方案更快,因为它是一种非阻塞解决方案. (2认同)