【问题标题】:Indexing URL's in SQL Server 2005SQL Server 2005 中的索引 URL
【发布时间】:2010-09-15 09:21:45
【问题描述】:

在 SQL Server 2005 中处理存储和索引 URL 的最佳方法是什么?

我有一个 WebPage 表,用于存储有关网页的元数据和内容。我还有许多其他与 WebPage 表相关的表。它们都使用 URL 作为键。

问题是 URL 可能非常大,使用它们作为键会使索引变得更大和更慢。多少我不知道,但我已经读过很多次使用大字段进行索引是要避免的。假设 URL 是 nvarchar(400),它们是用作主键的巨大字段。

有哪些选择?

使用 URL 作为键而不是较小的字段可能会有多大的痛苦。

我查看了具有标识列的 WebPage 表,然后将其用作 WebPage 的主键。这使所有相关的索引更小更高效,但它使导入数据有点痛苦。关联表的每次导入都必须先查找 url 的 id 是什么,然后再将数据插入表中。

我也尝试过在 URL 上使用哈希来创建更小的索引,但我仍然不确定这是否是最好的处理方式。它不会是唯一索引,并且会受到少量冲突。所以我不确定在这种情况下会使用什么外键......

数据库中将存储数百万条关于网页的记录,并且会有大量的批量更新。此外,还会有大量活动读取和汇总数据。

有什么想法吗?

【问题讨论】:

    标签: sql-server performance


    【解决方案1】:

    我会坚持使用哈希解决方案。这会生成一个具有相当低碰撞机会的唯一密钥。

    另一种方法是创建 GUID 并将其用作键。

    【讨论】:

    • 如果您使用哈希解决方案,相关表使用什么作为外键?你不能使用哈希,因为你会发生冲突?
    • 我认为 GUID 解决方案与具有标识列相同。在相关表中使用 GUID 之前,每个导入程序都必须点击 WebPage 表以将 URL 转换为 GUID。
    • 就主键的哈希值而言,如果您的页数足够低以防止冲突,您将拥有一个唯一标识符。相关表应该没有问题。安德鲁,我误会你了吗?
    • 会有大量记录,所以我不能真正相信哈希是唯一的。我可以在主表上使用它,以加快搜索网页的速度。然后对相关表使用网页主键...
    • 这就是我的意思 - 抱歉没有更清楚。正如您所说,主要问题是主表中的庞大数量。
    【解决方案2】:

    我会使用普通的标识列作为主键。你说:

    这使所有关联的索引更小更高效 但它使导入数据有点痛苦。每次导入 关联表必须首先查找 url 的 id 是什么 在表中插入数据之前。

    是的,但痛苦可能是值得的,您在此过程中学到的技术将在未来的项目中非常宝贵。

    在 SQL Server 2005 上,您可以创建类似于以下内容的用户定义函数 GetUrlId

    CREATE FUNCTION GetUrlId (@Url nvarchar(400)) 
    RETURNS int
    AS BEGIN
      DECLARE @UrlId int
      SELECT @UrlId = Id FROM Url WHERE Url = @Url
      RETURN @UrlId
    END
    

    这将返回 URL 表中已有 URL 的 ID,对于尚未记录的任何 URL,返回 NULL。然后你可以在你的 import 语句中调用这个函数——比如

    INSERT INTO 
      UrlHistory(UrlId, Visited, RemoteIp) 
    VALUES 
      (dbo.GetUrlId('http://www.stackoverflow.com/'), @Visited, @RemoteIp)
    

    这可能比正确的连接语句慢,但对于一次性或偶尔的导入例程,它可能会使事情变得更容易。

    【讨论】:

    • 我喜欢您的回答 - 您可以将其与 url 散列结合起来,并有 2 种方法来唯一标识一个页面。
    • 您必须在 Url 列上仍然有索引(显然将 UrlID 作为集群),否则您的查找将花费很长时间。
    【解决方案3】:

    根据您关心的位将 URL 分成几列,并使用 RFC 作为指导。反转主机和域信息,以便索引可以像域一样分组(Google 会这样做)。

    stackoverflow.com      -> com.stackoverflow  
    blog.stackoverflow.com -> com.stackoverflow.blog
    

    Google 有一篇论文概述了他们的工作,但我现在找不到。

    http://en.wikipedia.org/wiki/Uniform_Resource_Locator

    【讨论】:

      【解决方案4】:

      我完全同意迪伦的观点。使用 IDENTITY 列或 GUID 列作为 WebPage 表中的代理键。那是一个干净的解决方案。我认为在导入时查找 id 并没有那么痛苦。

      使用大的 varchar 列作为键列会浪费大量空间并影响插入和查询性能。

      【讨论】:

        【解决方案5】:

        不是一个解决方案。更多另一种观点。

        存储页面的全部唯一 URI 可能会破坏 URI 构造的部分要点。每个正斜杠都应该指代域内的唯一语义空间(无论该空间是实际的还是逻辑的)。除非您打算存储的 URI 与 www.somedomain.com/p.aspx?id=123456789 类似,否则实际上最好将单个 URI 元表分解为代表您在站点中表示的子域的表.

        例如,如果您要将多个“新闻”部分 URI 保存在与“评论”URI 相同的表中,那么您就错过了拥有一个内容包含有关元信息的“部分”表的技巧该部分,并且其自己的 ID 充当其中所有这些 URI 的父级。

        【讨论】:

          猜你喜欢
          • 2011-07-16
          • 1970-01-01
          • 2011-05-10
          • 2011-05-25
          • 2010-09-17
          • 2010-10-27
          • 2014-01-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多