如何将一个非常大的 lucene 结果集连接到一个真正的大型 sql 表 [10 的百万行]

Posted

技术标签:

【中文标题】如何将一个非常大的 lucene 结果集连接到一个真正的大型 sql 表 [10 的百万行]【英文标题】:How to join a very large lucene resultset to a real large sql table [10's of million rows] 【发布时间】:2013-07-24 07:39:15 【问题描述】:

问题来了,

我有一个 SQL 数据库,其中包含您的常规客户、产品、订单模式,但非常庞大。 [每张表有 10 万行]。还有一个带有 order_email [大约 1 亿行] 的大表。此表包含与订单关联的所有电子邮件通信。我已经在 order_email 之上实现了全文搜索,效果很好。

现在我想扩展电子邮件搜索功能以根据其他域对象进行过滤。即回答诸如

之类的查询 显示发送电子邮件中包含“永不放弃”短语的客户 显示包含“更多小马”短语的关联电子邮件的订单。

实现是对 lucene 结果和 sql 结果进行交集/连接,但由于涉及的表和索引的大小,我想不出一种方法来不遇到问题

我失败的方法

蛮力。将我的大部分数据库列添加为 lucene 字段。这相当于对我的整个数据库进行非规范化并创建一个包含所有列作为字段的 Lucene 索引(以 Terrabytes 为单位的大小)。性能很差而且成本过高。

获取 Lucene 结果集,从中获取 OrderID 并查询数据库,例如 SELECT * from Order where OrderID IN(ORDERIDs from Lucene)。这不起作用,因为电子邮件搜索可能会产生一百万个 orderID,这会使 SQL 查询的性能很差。

在应用程序代码中执行连接,但迭代 sql 结果和 lucene 结果。这意味着根据结果的大小,单个查询可以加载 2 百万行数据集并对其进行迭代,从而浪费 CPU 和内存。

关于如何构建这两个大型数据集的连接/交集的想法?

ps:第一个建议 hadoop 是一个臭鸡蛋。希望可以,但我们没有更多硬件的预算。

【问题讨论】:

好的,别介意最后的评论。看,如果你想显示一个基于客户表的结果集,由 lucene 过滤,你可以像你的第 2 点那样分两个步骤来完成。但是,不要向您的应用用户显示一百万个 orderID - 对它们进行分页。然后 SELECT * from Order where OrderID IN (ORDERIDs from Lucene, count is constrained by your page size) 您的结果是否必须始终包含匹配的字段?例如,在搜索发送带有短语 X 的电子邮件的客户时,您必须在结果中显示该电子邮件还是仅显示该客户就足够了? 我们的索引涵盖了一个有 300M 行的表,以及一个有 10+ 百万行的表,而我们只接近 15GB 左右。你怎么知道它的数量级是 TB?您是否尝试过不在 Lucene 中存储实际文本,而只是进行 SQL 查找以显示结果? 我的意思是,如果我对整个数据库进行非规范化并为其编制索引,那么该索引将以 TB 为单位。您如何将索引中的结果与 SQL 相匹配?您是否执行“从 tbl 中选择 id in (ids from index)?” 我认为您应该尝试将所有数据放入 Lucene。它可能不会像您想象的那样使用那么多的存储空间。可能值得一试。 【参考方案1】:

就像 OzrenTkalcecKrznaric 在 cmets 的问题中所说,分页是你的朋友。 (请记住,有史以来最强大的算法是“分而治之”。)

【讨论】:

以上是关于如何将一个非常大的 lucene 结果集连接到一个真正的大型 sql 表 [10 的百万行]的主要内容,如果未能解决你的问题,请参考以下文章

将 2 个立方体中的 2 个数据集连接到 s-s-rS 上的一个图表中

我可以将搜索引擎(solr搜索或lucene搜索)集成到Maximo中吗?

Solr/Lucene使用docValue查询的一个坑

lucene3.0 通过IndexSearcher.doc(i)获取Document 非常慢,如何提高性能?

5分钟了解搜索引擎Lucene的原理

Java/Spring:连接到多个 BigQuery 数据集