- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想在内容表中的标题和关键字上搜索请求的术语 ($q),同时也搜索模型,这些模型位于另一个表中并由中间的表链接。另外,我需要获取另一个表中的 View 数。
这是我到目前为止一直在处理的查询,结果很好,但太慢了(当我在 PhpMyAdmin 中运行它时,平均 0.6 秒......我们每月有数百万访问者)
SELECT DISTINCT SQL_CALC_FOUND_ROWS
c.*,
cv.views,
(MATCH (c.title) AGAINST ('{$q}') * 3) Relevance1,
MATCH (c.keywords) AGAINST ('{$q}') Relevance2,
(MATCH (a.`name`) AGAINST ('{$q}') * 2) Relevance3
FROM
content AS c
LEFT JOIN
content_actors AS ca ON ca.content = c.record_num
LEFT JOIN
actors AS a ON a.record_num = cm.actor
LEFT JOIN
content_views AS cv ON cv.content = c.record_num
WHERE
c.enabled = 1
GROUP BY c.title, c.length
HAVING (Relevance1 + Relevance2 + Relevance3) > 0
ORDER BY (Relevance1 + Relevance2 + Relevance3) DESC
表架构如下所示:
content
record_num title keywords
1 Video1 Comedy, Action, Supercool
2 Video2 Comet
content_actors
content model
1 1
1 2
2 1
actors
record_num name
1 Jennifer Lopez
2 Bruce Willis
content_views
content views
1 160
2 312
这是我通过执行 SHOW INDEX FROM tablename 找到的索引:
Table Column_Name Seq_in_index Key_name Index_type
---------------------------------------------------------------------------
content record_num 1 PRIMARY BTREE
content keywords 1 keywords FULLTEXT
content keywords 2 title FULLTEXT
content title 1 title FULLTEXT
content description 1 description FULLTEXT
content keywords 1 keywords_2 FULLTEXT
content_actors content 1 content BTREE
content_actors actor 2 content BTREE
content_actor actor 1 actor BTREE
actors record_num 1 PRIMARY BTREE
actors name 1 name BTREE
actors name 1 name_2 FULLTEXT
content_views content 1 PRIMARY BTREE
content_views views 1 views BTREE
这是查询的解释:
ID SELECT_TYPE TABLE TYPE POSSIBLE_KEYS KEY ROWS EXTRA
1 SIMPLE c ref enabled_2, enabled enabled 29210 Using where; Using temporary; Using filesort
1 SIMPLE ca ref content content 1 Using index
1 SIMPLE a eq_ref PRIMARY PRIMARY 1
1 SIMPLE cv eq_ref PRIMARY PRIMARY 1
我使用 GROUP BY 来避免重复内容,但单独使用该 group by 似乎会使处理查询所需的时间增加一倍。
编辑 好吧,在玩了一下查询之后,我意识到,如果我删除 GROUP BY,我会得到重复项,如果我让 GROUP BY 在那里,它不会不采用正确的 Relevance3 值(如果没有 GROUP BY,一个会返回 Relevance3 的值,而另一个则不会...)
最佳答案
将MATCH
(或运算)添加到WHERE
- 这将显着减少SQL_CALC_FOUND_ROWS
中要处理的行数code> 并消除对 HAVING...
的需要。
而不是
cv.views,
...
LEFT JOIN content_views AS cv ON cv.content = c.record_num
做
( SELECT views FROM content_views ON content = c.record_num ) AS views,
编辑
需要LEFT
和GROUP BY
,因为actors
是可选的,并且可能有多个actors
。由于您根本不需要 Actor 姓名,因此您可以通过执行以下操作来摆脱它
WHERE ... AND ( EXISTS SELECT *
FROM content_actors
JOIN actors AS a ON ...
WHERE MATCH (a.`name`) AGAINST ('{$q}')
AND ca...
)
但这并不能让您在 ORDER BY
中包含相关性。
因此,您需要使用 UNION DISTINCT
构建一个子查询。将有 2 个SELECT
:
选择#1:
SELECT c.id,
3 * MATCH(c.title) AGAINST ('{$q}')
+ MATCH(c.keywords) AGAINST ('{$q}') AS relevance
FROM Content AS c
WHERE MATCH(c.title, c.keywords) AGAINST ('{$q}')
(并且有 FULLTEXT(title, keywords))这将有效地获取有用的
content` 行的 id。
选择#2:
SELECT c.id,
2*MAX(MATCH(a.actor) AGAINST ('{$q}') AS actor_rel) AS relevance
FROM content AS c
JOIN content_actors ca ON ca.content = c.record_num
JOIN actors a ON a.record_num = ca.actor
WHERE MATCH(a.actor) AGAINST ('{$q}')
GROUP BY c.id;
确保有content_actors: INDEX(actor)
和content: INDEX(record_num)
。此SELECT
将有效地从actors
开始并返回到content
。请注意,当两个参与者 MATCH
时,它会执行与您的代码不同的操作;希望我的 MAX
是一个更好的解决方案。
现在,让我们把事情放在一起......
选择#3:
SELECT id, SUM(rel) AS relevance
FROM ( ... select #1 ... )
UNION ALL
( ... select #2 ... )
GROUP BY id
但这还不是全部......
选择#4:
SELECT c.*,
( ... views ... ) AS views
FROM ( ... select #3 ... ) AS u
JOIN content c ON c.id = u.id
我建议您手动运行每个步骤来验证它们,逐渐将所有部分组合在一起。是的,它很复杂,但应该相当快。
关于mysql - 优化跨多个表的全文搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35317501/
有没有办法对 Subversion 存储库执行全文搜索,包括所有历史记录? 例如,我编写了一个在某处使用过的功能,但后来不需要它,所以我对文件进行了 svn rm'd,但现在我需要再次找到它以将其用于
如何进行 MySQL 搜索,既匹配部分单词,又提供准确的相关性排序? SELECT name, MATCH(name) AGAINST ('math*' IN BOOLEAN MODE) AS rel
我在 postgresql 中创建了一个用于全文搜索的索引。 CREATE INDEX pesquisa_idx ON chamado USING gin(to_tsvector('portugues
我已经设置了一个数据库并启用了全文搜索,当我使用以下内容搜索数据库时,数据库中有一些条目包含“测试”一词,还有一个条目包含“测试更多”: SELECT keywords, title FROM dat
我想知道是否可以进行 MATCH() AGAINST()(全文)搜索,使得不直接相邻的单词需要按特定顺序排列?在我的网站上,当用户在双引号之间键入单词时,搜索将仅显示具有特定顺序的这些单词的结果。例如
我有一个 80,000 行的数据库,当我测试一些 FULLTEXT 查询时,我遇到了一个意想不到的结果。我已从 MYSQL 中删除停用词并将最小字长设置为 3。 当我执行此查询时: SELECT `s
我刚刚在我的 MYSQL 数据库中发现了一堆流氓数据... 到达它的唯一方法是通过其中一列 - FILE_PATH,其中包含文件路径的斜杠剥离版本。我需要在这组文件中找到一些恶意文件——它们的文件名都
我正在为我的站点构建一个小的搜索功能。我正在接受用户的查询,提取关键字,然后针对提取的关键字运行全文 MySQL 搜索。 问题在于 MySQL 将词干视为文字。这是正在发生的过程: 用户搜索“棒球”之
这是一个关于使用(关系)数据库设计全文搜索的系统架构问题。我使用的具体软件是 Solr 和 PostgreSQL,仅供引用。 假设我们正在构建一个有两个用户 Andy 和 Betty 的论坛 -- P
当元素数组中的数组包含应与我的搜索匹配的文本时,我无法检索文档。 这里有两个示例文档: { _id: ..., 'foo': [ { 'name
我正在使用这个查询,但不幸的是它运行缓慢: SELECT *, (MATCH(`title`) AGAINST ('$word' IN BOOLEAN MODE) * 2 + MATC
我正在构建一个非常简单的产品目录,它将在 mysql 表中存储产品,我想尽快搜索产品(并尽可能相关)。产品数据库将非常大(大约 500.000 个产品),这就是为什么使用“like”而不使用索引的搜索
select count(distinct email_address) from users WHERE MATCH (email_address) AGAINST ('@r
我正在尝试在 mySQL 中进行简单的全文搜索,但在复数方面遇到一些问题。 我确实相信我符合50% 规则。 我不认为我使用了停用词。 我正在运行这样的查询: SELECT * FROM product
我在 innoDB 数据库中使用全文搜索时遇到了一个大问题。 首先,ns_pages 表有超过 2.6m 的记录,全文索引有 3 个键 block 。 该数据库在具有 128GB RAM 的 Dell
我有一个城市和州的数据库(大约 43,000 个)。我对其进行全文搜索,如下所示: select city, state, match(city, state_short, state) agains
我正在使用带有自然语言全文的 Mysql FULLTEXT 搜索,不幸的是,我遇到了 FULLTEXT 50% 阈值,如果给定的关键字出现在总行数的 50% 时间,则不允许我搜索行。 我搜索并找到了一
如果我搜索单词hello,那么我没有匹配到,而我搜索单词hella,那么我得到了匹配。同样的情况也发生在“Non”这个词上。我在 Mac 上的 MAMP 和 sqlfiddle.com 上进行了测试,
所以我有一个简单的场景。我有一张 field 表(事件 field 等)。我的查询看起来像: SELECT * FROM venues WHERE venues.name % 'Philips Are
我有一个表,其中有视频数据,如“标题”、“描述”等。我正在尝试使用 MySQL 全文索引编写一个搜索引擎。 SQL 查询适用于某些单词,但不是每个单词。这是我的 SQL 查询; SELECT * FR
我是一名优秀的程序员,十分优秀!