代码之家  ›  专栏  ›  技术社区  ›  Simon_Weaver

索引一个“不可猜测”的键以便快速检索?

  •  1
  • Simon_Weaver  · 技术社区  · 15 年前

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

    我有一个会话密钥,作为cookie发送给客户机。这是GUID。 我还有一个代理身份int列。

    在客户机的生命周期中,我经常需要访问会话行以对其进行更新。我担心的是找到这个会话行进行更新。

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

    a)我不想要我的技术“黑客” 用户能够测量用户 他们是-也就是说,知道有多少人 我们总共去了那个地方

    b)我想确保没有人恶意地干扰数据-没有人能猜到guid

    我知道guid索引是无效的,但我不确定效率到底有多低。我也不清楚如何最大限度地提高同一行的多个更新的效率。

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

    • 为guid列编制索引,并始终使用该列查找行
    • 执行表扫描以根据guid查找行(假设最近的会话很容易找到)。按相反的日期顺序(如果可能的话!)
    • 避免使用guid索引,并在活动会话的应用层中保留哈希表: IDictionary<GUID, int> 允许从“非机密”GUID密钥中找到“机密”标识代理项。

    一天可能有几千个疗程。

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

    3 回复  |  直到 15 年前
        1
  •  4
  •   Andomar    15 年前

    在这种情况下,我只需要在guid上创建一个索引。对于现代数据库来说,每天数千次会话完全是一个微不足道的负载。

    一些注释:

    • 如果将guid索引创建为非聚集索引,则该索引将很小,可能会缓存在内存中。默认情况下,大多数数据库都聚集在主键上。
    • guid列大于整数。但这在当今几乎不是一个大问题。您需要应用程序的GUID。
    • guid上的索引就像字符串上的索引,例如姓氏。这很有效。
    • GUID上索引的B树比标识列上的索引更难平衡。(但不比姓氏的索引更难。)这种效果可以通过从低填充因子开始,然后在每周的作业中重新组织索引来消除。对于每小时处理一百万个插入的数据库来说,这是一个微观优化。
        2
  •  2
  •   Peter Stuer    15 年前

    假设您使用的是SQL Server 2005或更高版本,那么您的场景可能会从newSequentialID()中受益,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的开销是否足以引起应用程序的注意。与实现自定义缓存场景(如您提议的字典)相比,您最好专注于最小化到数据库的往返。

        3
  •  1
  •   Schwern    15 年前

    如果我理解您的要求,您担心索引和通过散列的guid查找用户可能会减慢应用程序的速度?我和andomar在一起,这不太重要,除非插入的行太快,以至于更新索引会减慢速度。只有在像日志记录表这样的东西上才可能发生这种情况,然后只针对复杂的指标。

    更重要的是,你 先分析一下 是吗?你不必猜测为什么你的程序很慢,你可以通过一个分析器找出哪些比特很慢。否则,您将浪费大量时间优化a)从未使用或b)已经足够快的代码位。