MYSQL / PHP连接基于另一个表中的文本片段

时间:2017-02-06 19:09:10

标签: php mysql

我有2张桌子。我试图找到一种有效的方法来加入表格,基于第二个表格中包含的一段文字:

Table A (documents): 
+-------------+----------------------------+
| document_id | document_text              |
+-------------+----------------------------+
| 1           | My favorite color is blue  |
+-------------+----------------------------+
| 2           | My favorite color is green |
+-------------+----------------------------+
| 3           | Yellow is my favorite      |
+-------------+----------------------------+
| 4           | I like all colors          |
+-------------+----------------------------+
Table B (snippet): 
+------------+--------------+
| snippet_id | snippet_text |
+------------+--------------+
| 1          | orange       |
+------------+--------------+
| 2          | black        |
+------------+--------------+
| 3          | yellow       |
+------------+--------------+
| 4          | green        |
+------------+--------------+
| 5          | blue         |
+------------+--------------+

目前我能做到的唯一方法是在我的脚本中有两个独立的循环 - 第一个在表B上,然后另一个根据从表B中获得的片段查询表A.

它有效,但在我的真实世界数据中,片段是长句子,而表格A可以包含数千行,文本很多。

即使数据不多,尝试通过mysql查询也需要加载3分钟。

SELECT * FROM table_b left join table_a on document_text LIKE  CONCAT('%', snippet_text, '%')

因此,对于样本数据,所需的结果将是

+-------------+----------------------------+-----------+
| document_id | document_text              | snippet_id |
+-------------+----------------------------+-----------+
| 1           | My favorite color is blue  | 5         |
+-------------+----------------------------+-----------+
| 2           | My favorite color is green | 4         |
+-------------+----------------------------+-----------+
| 3           | Yellow is my favorite      | 3         |
+-------------+----------------------------+-----------+
| 4           | I like all colors          | NULL      |
+-------------+----------------------------+-----------+

3 个答案:

答案 0 :(得分:0)

快速的方法是在PHP中创建迭代器并从第二个查询中删除JOIN。如果你使用表之间的关系来做迭代器的成本(时间)比使用foreach更多,因为在PHP中。

尝试一下,不要分叉我!

答案 1 :(得分:0)

你在这里遇到挑战。 MySQL支持full text search,但需要注意的是搜索项必须是常量。

我的建议是在snippets上进行外循环。在循环内部分两步搜索“片段”,一个使用match,一个使用like(前者减少了第二个的行数)。然后将片段ID分配给那些。

所以,这反复做到:

select d.*, @snippetId
from (select d.*
      from documents d
      where match (d.document) against ( . . . ) 
     ) d
where d.document like ('%', @snippet, '%')

答案 2 :(得分:0)

您可以使用MySQL的locate功能,例如:

SELECT d.id, d.document, s.id
FROM documents d LEFT JOIN snippet s
ON LOCATE(s.snippet_text, d.document) <> 0
ORDER BY d.id;

Herelocate函数的文档。