【问题标题】:Do I have to create unique index for this?我必须为此创建唯一索引吗?
【发布时间】:2012-02-27 08:54:05
【问题描述】:

我正在制作自己的爬虫。现在我的问题是关于索引的。

我有 2 列是关于索引的。

一个是pageurl,另一个是hashcode 列。

pageurl 列是 VARCHARhashcode 列是 64 位 int

这是我正在执行的主要查询:

SELECT PageId FROM tblPages WHERE HashCode=biginthashcode AND PageUrl='pageurl'

PageId 是身份主键。

现在我用它作为索引:

CREATE nonclustered INDEX indexHashCode ON tblpages (hashcode)
INCLUDE (pageurl,pageid)

但由于软件的多线程特性,上述索引会导致过多的重复行。可能是SQL延迟造成的。

所以我必须像下面这样

CREATE UNIQUE nonclustered INDEX indexHashCode ON tblpages (hashcode,pageurl)
INCLUDE (pageid)

或者以某种方式使其不添加重复值。哪些是重复值?

重复值意味着 hashcode 和 pageurl 相同。如果不使用我的第一个索引创建像上面这样的唯一索引,这可能吗?

我使用的是 Microsoft SQL Server 2008。

【问题讨论】:

  • 如果你因为多线程而得到重复的行,这是否表明你的多个线程都在做同样的工作,这相当浪费精力?你的设置不清楚。例如,散列码是显示的页面的散列,还是 URL 的散列?如果您不想在表格中重复 URL 和哈希的组合,请创建一个索引以防止这种情况发生 - 哈希和 URL 的唯一索引。
  • 想象一下有 10 个进程一直在爬取页面。他们都从页面中找到数百个网址。所以他们中的大多数都是一样的。显然 sql server 延迟导致我的软件控制该 url 是否存在失败。所以我必须制作 sql server 以防止多次添加相同的 url。
  • 另外,标识列不一定是主键。如果您愿意(如果唯一),可以使用 URL 作为主键。
  • 它会导致 CPU 使用率过高。因此,我使用的是 64 位散列。我试过了。

标签: sql sql-server indexing duplicates unique


【解决方案1】:

正如 Jonathan Leffler 的评论所指出的,您可能在过程中试图解决问题为时已晚。为什么您的多线程代码首先会生成重复项?

也就是说,如果重复行创建是不可避免的,那么使用唯一索引可能是合理的。但是,您仍然想在插入行之前检查它们是否存在 - 通常使用存储过程。无论哪种方式,包含检查和插入的事务都应该防止重复。

最后,不管怎样,哈希码通常不会存储在数据库中。它们不是唯一的,因此两个 URL 可能具有相同的哈希码。

【讨论】:

  • 感谢您的回答,但您似乎没有理解这里的问题。问题是我有很多爬虫进程。他们正在抓取页面并多次找到相同的网址。我已经在检查数据库中的 url 是否存在,但显然 sql server 延迟导致失败。所以我必须让 sql server 阻止相同的值插入。
  • 不,他做到了。您的代码方法已损坏。有一个很好的方法来处理这个在中间的队列,并避免从双 url 插入开始。不完全是黑色科学-只是“不是初级程序员级别”。是的,我运行的系统比你的爬虫做得更多。 96 线程,没有双打。我在系统的早期处理它们。
  • 好吧,与其告诉它应该是这样,展示一些好的例子会更有好处。每个人都可以计划它应该是每个人都在不断讲述的方式,但没有任何合适的例子。所以我正在制定自己的解决方案。例如,现在我可以根据需要设置线程计数器,但我什至找不到设置要始终运行的线程数的单个示例。是的,我当前的系统一直保持一定数量的线程。
  • 我们在这里为您提供帮助,但您希望使用搜索引擎并进行一些试验和错误来弄清楚如何做您想要的。在这种情况下,问题不在于线程的数量——所有重要的爬虫都是多线程的——而是你有一个被你自己的代码违反的期望(没有唯一的行)。我们要说的是,根据我们在此类事情上的多年经验,如果您尝试阻止代码生成重复项,那么您最终会得到更好的结果。
【解决方案2】:

如果 (hashcode,pageurl) 已经存在,您似乎只想更新。在这种情况下,请查看here 以获取您的选择。

如果您不想更新,但不想插入新值,您还有很多选择(查询并检查它是否存在,或从给定链接修改解决方案...或其他),但很可能您在线程中做了一些不好的事情,因为许多线程都在做同样的工作,并且对于所有线程(除了一个),您只会丢弃结果。

【讨论】:

  • 实际上我正在检查该哈希码和 pageurl 组合是否存在。但显然是由于 sql server 多个线程添加多次相同的哈希码和 pageurl 组合的延迟。所以我希望 sql server 防止多次添加相同的哈希码和 pageurl 组合。
  • 您是否将“检查是否存在”+“插入”代码包装到事务中?如果你把它包装成事务,一切都应该没问题。
  • 不,我不这样做。这是我的插入命令,你可以修改它吗? pastebin.com/wYjCqs2y
  • 你在哪里检查它是否已经存在?请查看我在答案中指出的 SO 链接中的答案...但我仍然认为您的线程做的工作太多,您应该更好地同步它们:)
  • 现在我添加到查询如果不存在开始插入结束。我希望这样不会有任何重复。现在就等着瞧吧:)
猜你喜欢
  • 2011-05-18
  • 1970-01-01
  • 1970-01-01
  • 2012-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多