【问题标题】:Best way to deal with datetime when storing records for a search engine in MySQL?在 MySQL 中存储搜索引擎记录时处理日期时间的最佳方法?
【发布时间】:2015-01-03 20:48:53
【问题描述】:

我有一张桌子:

URL | last_crawled | worker_id | worker_assign_date

url 显然是任何 url。 last_crawled 是一个日期字段,用于存储上次抓取该字段的时间。工作人员 ID 是当前分配给此 URL 的工作人员的 ID。 worker_assign_date 是 URL 分配给爬虫的时间。这样一来,如果 worker X 抓取 URL 的时间过长,我只会将该 URL 分配回另一个 worker。

我的问题是,由于我将大量按 worker_assign_date 和 last_crawled 进行排序,该类型应该是什么?

第一要务是速度,哪个排序更快?整数还是日期时间?

第二个优先级是大小。 int 占用的空间是否比 DateTime 少或更多?

请注意:互联网大约有 50 亿页。该数据库将保存所有 500 万个 URL 并进行更新等。我将使用 InnoDB,因此我只能锁定单行。

更新

在 2099 年之前“工作”的 unix 时间戳将是 4099770061,因此将其存储为 INT(10) 就足够了。根据 mysql documentation,这将占用 4 个字节。一个日期时间字段将占用 8 个字节。因此,似乎时间戳至少更小。这是真的吗?

此外,最后一个问题仍然存在,在排序过程中哪个更快?有什么区别吗?

【问题讨论】:

  • 嘿@coderama,我强烈推荐日期时间。我公司的 DBA 推荐它,我们维护一个大型的 mySQL 堆栈。另外,请参考这篇 stackoverflow 文章:stackoverflow.com/questions/12617347/…
  • 谢谢,但基于什么理由。我不会使用任何日期函数。纯粹是为了订购。我已经确定日期时间更大,但它是更慢还是更快?如果我不需要使用所有额外的 mysql 功能,我为什么要使用两者中更大更慢的?
  • 如果只是为了订购,我同意 int 会更好。但是,您可能还需要考虑您的数据库将来将用于什么。您现在可能不需要日期函数,但您的数据存储不可避免地会变得更大,并且您会想要报告该数据。如果你能在这种情况下利用 mySQL 的日期函数,会容易很多。
  • 如果您正在构建某种网络爬虫,我认为尤其如此。一个 URL 的一个数据库行将加起来 FAST。
  • 太棒了。有什么想法可以更快地排序吗?我认为 int,因为它更小,但也许我不知道 date_time 有一些好处?

标签: mysql


【解决方案1】:

我发现一篇文章解决了您的确切问题。 Int 明显更快。这个线程有一个人运行性能测试,非常支持 int over datetime。

MySQL Integer vs DateTime index

【讨论】:

  • 谢谢!这完美地回答了它。
【解决方案2】:

分区?

如果这是您将日期放入数据库中的边缘情况之一,并且不想对它做任何事情,直到以后;那么我会考虑按日期、月份、日期、年份等之一进行 分区

http://dev.mysql.com/doc/refman/5.6/en/partitioning-overview.html

整数还是日期时间?

  • 整数是一种更原始​​的类型,不使用那么多字节。
  • 在 32 位机器上,比较 ​​4 个字节比比较 8 个字节要快。
  • 请记住,分辨率很重要,
    • DATE 是 3 个字节
    • YEAR 单独只有 1 个字节

做好功课

根据您的工作量(写入密集型?读取密集型?)以及您在哪里进行从时间戳到整数的转换,您可能会有一些惊喜。我不会相信我看到的数字并进行自己的实验以确保是否适合我的工作量。

http://dev.mysql.com/doc/refman/5.1/en/storage-requirements.html http://dev.mysql.com/doc/internals/en/date-and-time-data-type-representation.html


如果您的最终目标是继续抓取您上次抓取时间最长的页面;您可以想象一个环,其中所有行都有一个定期增加的数字,当再次抓取 url 时,您可以将该数字重置为零。

分区,续。

如果您使用分区并且知道分区 p1 具有最旧的分区。

SELECT URL FROM mytable PARTITION (p1);
# crawl those.

下一次,假设p2 拥有最旧的数据。

SELECT URL FROM mytable PARTITION (p2);
# crawl those.

繁荣,不需要排序或排序。

如何选择好的分区方案。

50 亿页是很多。你不会在一天之内抓取它(或者我希望你没有使用拨号)。如果您的搬家窗口是一周,那么一年大约有 52 周;每周你都会得到一个新的工作集。

http://dev.mysql.com/doc/refman/5.6/en/partitioning-selection.html

【讨论】:

  • 这对我有什么好处?有几个较小的 int 字段而不是一个大字段更好吗?记住,只有排序!由于必须合并字段,这不会使其变得更加困难吗?
  • 我怀疑 XY 问题。最终目标是根据某些标准(例如超过一个月)对给定的数据子集(分区?)进行排序或操作吗?
  • 思路是“按lastcrawled asc排序”,这样就可以得到最久之前爬过的URL。有道理?我愿意接受任何建议,以确保首先订购最旧的记录。上次抓取的日期字段似乎很有意义。
  • 我理解那部分,但是这样订购它们有什么目的吗?
  • 没有。它只确定爬取顺序。有一个只存储链接的数据库(mysql 数据库中有 50 亿行)。抓取 url 后,会将结果传递到 solr 数据库进行索引。所以数据有两个索引。
猜你喜欢
  • 2011-04-16
  • 1970-01-01
  • 1970-01-01
  • 2010-10-05
  • 2012-10-09
  • 2011-06-02
  • 1970-01-01
  • 1970-01-01
  • 2012-10-27
相关资源
最近更新 更多