【问题标题】:Web crawler SQLite3 SELECT for next link to crawl is crazy slow网络爬虫 SQLite3 SELECT 用于下一个要爬取的链接非常慢
【发布时间】:2021-03-30 05:20:56
【问题描述】:

我正在用 python 制作网络爬虫,但遇到了 sqlite 查询问题。查询有效,但速度很慢,有没有更好的方法来做到这一点?通常我对 sql 的使用非常好,但我真的遇到了所有这些参数的限制。

表链接包含从网站爬取的链接 (href="LINK")。 下面的 sql 输出了接下来要爬取的链接。

在特定时间,主机上只能抓取 x 数量的网站。

SELECT *,
(SELECT COUNT(*) FROM links AS b WHERE b.hostname = a.hostname and b.lastCrawledTimestamp < ?)
AS hostLimitCount
FROM links AS a WHERE hostLimitCount < ? and lastCrawledTimestamp < ?
LIMIT 1

lastCrawledTimestamp 有一个索引
主机名有一个索引

谢谢!

【问题讨论】:

  • 为什么要添加“mysql”标签?您可以向 Sqlite 询问 query plan 并在问题中以正确格式显示它。它可能会揭示更多信息。
  • 它使用几乎相同的语法。如果有人只会说“MySQL语法”,他也可以帮助我,甚至对SQLite一无所知。问题不是关于 SQLite,更多的是关于 SQL 本身。此外,如果其他人对 MySQL 有这个问题,那么他可能会使用相同的解决方案。事实上,上面的 SQL 可以用于 MySQL AND SQLite。
  • SQL 差异很大。 看起来 像 MySQL 代码。 MySQL可以处理复合索引; Sqlite可以吗?
  • 是的,我知道.. 但你知道我的意思.. 显然你比我知道的更多。

标签: python mysql performance sqlite web-crawler


【解决方案1】:

子查询将受益于

INDEX(hostname, lastCrawledTimestame)

另外,像下面这样把它翻过来可能会有所帮助:

SELECT  a.*, x.hostLimitCount
    FROM  
        (
        SELECT  b.hostname, COUNT(*) AS hostLimitCount
            FROM  links AS b
            WHERE  b.lastCrawledTimestamp < ?
            GROUP BY hostname
            HAVING  hostLimitCount < ?
            LIMIT  1 
        ) AS x
    JOIN  links AS a USING(hostname) 

这可能会受益于相同的索引。

【讨论】:

  • 非常感谢。我想我应该更多地了解 Joins 和这些东西......您的查询速度快了一百万倍。
  • @Pitchbloas - 在这种情况下的原则是做一个“派生表”,有效地减少行数,然后达到其他列。并且索引是“覆盖”的。
猜你喜欢
  • 1970-01-01
  • 2016-05-26
  • 1970-01-01
  • 1970-01-01
  • 2013-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-15
相关资源
最近更新 更多