索引“不可猜测”的密钥以便快速检索?

时间:2009-05-24 07:58:29

标签: sql performance

我并没有完全从谷歌分析中得到所有我想要的,所以我正在制作我自己的简单跟踪系统来填补一些空白。

我有一个会话密钥,我将其作为cookie发送给客户端。这是一个GUID。 我还有一个代理IDENTITY int列。

我经常需要访问会话行,以便在客户端生命周期内对其进行更新。找到这个会话行来进行更新是我关心的问题。

我只将GUID发送到客户端浏览器:

  

a)我不想要我的技术“黑客”   用户可以控制用户的内容   id'他们是 - 即知道多少   我们共有网站的访客

     b)我想确保没有人对数据进行恶意混淆 - 没人能猜出GUID

我知道GUID索引是无效的,但我不确定究竟效率如何。我也不清楚如何最大限度地提高同一行的多次更新效率。

我不知道应该做以下哪一项:

  • 索引GUID列并始终使用它来查找行
  • 执行表扫描以根据GUID查找行(假设最近的会话很容易找到)。通过反向日期顺序执行此操作(如果可能的话!)
  • 避免使用GUID索引并在我的活动会话应用程序层中保留哈希表:IDictionary<GUID, int>以允许从“非秘密”GUID密钥中找到“秘密”IDENTITY代理密钥。

每天可能有几千个会议。

PS。我只是想更好地理解这方面的SQL方面。我知道我可以做其他聪明的工作,比如只在会话到期等时写入表格,但请保持与SQL /索引相关的答案。

3 个答案:

答案 0 :(得分:4)

在这种情况下,我只是在GUID上创建一个索引。每天数以千计的会话对于现代数据库来说是一件非常重要的工作。

一些注意事项:

  • 如果将GUID索引创建为非群集,则索引将很小并且可能会缓存在内存中。默认情况下,大多数数据库都在主键上进行集群。
  • GUID列大于整数。但现在这不是一个大问题。并且您需要应用程序的GUID。
  • GUID上的索引就像字符串上的索引,例如Last Name。这很有效。
  • GUID上的索引的B树比标识列上的索引更难平衡。 (但不要比姓氏上的索引更难。)这种效果可以通过从低填充因子开始,并在每周工作中重新组织索引来抵消。这是对一小时或更长时间处理一百万次插入的数据库的微优化。

答案 1 :(得分:2)

假设您使用的是SQL Server 2005或更高版本,您的方案可能会受益于NEWSEQUENTIALID(),该函数为您提供有序的GUID。

请考虑文章Performance Comparison - Identity() x NewId() x NewSequentialId

中的这句话

“NEWSEQUENTIALID系统函数是对SQL Server 2005的补充。它试图将SQL Server 2000中需要冲突的需求集合在一起,即身份级别的插入性能和全局唯一值。”

将您的表声明为

create table MyTable( 
   id uniqueidentifier default newsequentialid() not null primary key clustered
  ); 

然而,请记住,正如Andomar所指出的那样,生成的GUID的顺序性也使它们易于预测。有一些方法可以使这更难,但不会使这比将相同的技术应用于顺序整数键更好。

与其他作者一样,我严重怀疑使用直接newid()GUID的开销足以让您的应用程序注意到。您最好尽量减少对数据库的往返次数,而不是实现自定义缓存方案,例如您建议的字典。

答案 2 :(得分:1)

如果我了解您的要求,您会担心索引并通过哈希GUID查找用户可能会降低您的应用程序速度吗?我和Andomar在一起,除非你快速插入行以至于更新索引会减慢速度,否则这不太重要。只有在记录表之类的东西可能会发生,然后才会发生复杂的指示。

更重要的是,您首先对其进行了分析吗?您不必猜测为什么您的程序很慢,您可以通过分析器找出哪些位慢。否则,你会浪费时间来优化A)从未使用或B)已经足够快的代码。