2009-05-24 45 views
1

我并没有完全从Google分析中获得所有我想要的,所以我正在使自己的简单跟踪系统填补一些空白。索引一个“不可猜测”的密钥以便快速检索?

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

我将经常访问会话行以在客户端生命周期中对其进行更新。查找此会话行以进行更新是我关心的地方。

只送上我的GUID到客户端浏览器:

一)我不想我的技术“黑客” 用户能够瓜哥什么用户 ID',他们是 - 即知道有多少 观众我们不得不在总

b中的网站),我想,以确保没有人弄乱与恶意数据 - 没有人能猜对GUID

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

我不知道下面我应该做的:

  • 指数GUID列,总是用它来找到该行
  • 做一个表扫描基础上找到的GUID的行(假设最近的会议很容易找到)。通过反向日期顺序来做到这一点(如果可能的话!)
  • 避免一个GUID索引并在我的活动会话应用层中保留一个散列表:IDictionary<GUID, int>允许从'非秘密中找到'秘密'身份代理键'GUID键。

每天可能会有几千个会话。

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

回答

4

在这种情况下,我只是在GUID上创建一个索引。对于现代数据库来说,每天数以千计的会话是一项完全微不足道的工作。

一些注意事项:

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

所以事实上,没有'订单'的GUIDs不应该关心我。该索引知道123456比123455更新,但失去了GUID的知识。我猜索引行为就像一个哈希表,无论你是在一个GUID或整数列索引吗?即找到'块'或其它任何东西,并扫描所请求的特定项目。这是一个正确的假设吗? – 2009-05-24 08:15:53

+0

索引是b树,而不是散列表。顺序无关紧要,Sql Server会将b-tree“走”到一个GUID和一个标识列。在步行结束时,它会找到对该行的引用(查找)。因此,您的假设是正确的。我在重新思考之后编辑了这篇文章。 :) – Andomar 2009-05-24 08:32:15

1

如果我明白你在问什么,你担心索引和通过散列GUID查找你的用户可能会减慢你的应用程序的速度?我与Andomar合作,除非你插入行速度太快,否则这不太重要,因为更新索引会降低速度。只有像日志记录表这样的事情发生,然后才会出现复杂的痕迹。

更重要的是,你是不是个人简介?你不必猜测你的程序为什么很慢,你可以通过分析器找出哪些位慢。否则,你会浪费数小时来优化A)从未使用或B)已经足够快的代码。

2

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

从文章Performance Comparison - Identity() x NewId() x NewSequentialId

考虑这个报价“的NEWSEQUENTIALID系统功能的附加到SQL Server 2005它旨在汇集,曾经被认为是,冲突在SQL Server 2000的要求,即identity-级别插入性能和全球唯一值。“

声明你的表作为

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

但是,请记住,作为Andomar指出,也产生的GUID的顺序性使他们很容易预测。有很多方法可以使这一点变得更加困难,但不是这样会比将相同的技术应用于顺序整数键更好。

与其他作者一样,我严重怀疑使用直接newid()GUID的开销会足够大以使您的应用程序能够注意到。您最好将注意力放在最小化往数据库的往返行程上,而不是实现自定义缓存方案,例如您建议的字典。