【问题标题】:MySQL Match Against w/ additional condition: Use subquery?带有附加条件的 MySQL 匹配:使用子查询?
【发布时间】:2020-04-13 06:59:01
【问题描述】:

假设我们有一个表格,比如

CREATE TABLE test{
title VARCHAR(32),
city VARCHAR(32),
description TEXT
...

在查询中说我们有

SELECT * FROM test WHERE MATCH(title, description) AGAINST('xyz' IN NATURAL LANGUAGE MODE) AND city = 'ABC';

MySQL 会知道首先使用“城市”条件,还是我们应该更明确地使用子查询?

【问题讨论】:

  • 这取决于索引和统计数据。view the query plan 看看 MySQL 实际选择了什么。
  • 写入多个索引:stackoverflow.com/a/12222699/2864740;查询规划器仍然可能选择使用 [附加] 索引,基于 carnality 估计。这就是为什么查看实际查询计划(可能会随着时间而改变!)很重要的原因。
  • 请参阅stackoverflow.com/q/12427110/2864740 了解一些注意事项。大概是个骗局​​。问题也是..
  • 无论如何,回到标题:子查询不太可能更有效。无论如何,非依赖子查询在逻辑上都是“展开”的。如果这以某种方式触发查询计划器中的行为更改,则打开 YMMV。见第一条评论。
  • 请提供EXPLAIN SELECT 用于所述查询,并交换AND 子句。 (粘贴的文本版本就足够了。)

标签: mysql sql where-clause database-performance match-against


【解决方案1】:

通过查看代码,MATCH 表达式将在查询优化阶段进行评估。这意味着在考虑city 的条件之前,将识别所有包含'xyz' 的行。 (至少,这是我对 InnoDB 工作的理解。我不知道如何在 MyISAM 中实现的细节。)在查询执行期间,当评估 WHERE 子句时,表达式从左到右评估。 (这是当前的实现,可能会在未来的版本中更改。)由于已经计算了 MATCH 分数,因此此时只需评估它们是否为非零。

如果您的city 列已编入索引,则查询优化器可能会选择使用此索引来仅扫描来自给定城市的行,并仅比较这些行的 MATCH 分数。但是,仍然首先识别包含'xyz' 的所有行。查询的 EXPLAIN 输出将显示是否使用了索引。

我怀疑使用子查询会有所帮助。如果子查询是相关的,您甚至可能冒着执行多次全文搜索的风险。

【讨论】:

  • 那么如果city在比赛前放在左边,会有优势吗?我不确定 EXPLAIN,但另一个条件确实已编入索引。 EXPLAIN 将其标识为“可能的密钥”。
  • 嗯...我一直认为(1)WHERE 中的顺序无关紧要(子查询等极端情况除外),以及(2)MATCH 始终执行第一的。 (我认为 MyISAM 表示它会首先发生。)
  • 将城市放在首位,只会带来很小的改进,因为 MATCH 的大部分“繁重”工作已经在查询优化期间完成了。
猜你喜欢
  • 1970-01-01
  • 2013-08-28
  • 1970-01-01
  • 1970-01-01
  • 2011-07-06
  • 2011-04-28
  • 2017-05-22
  • 1970-01-01
  • 2011-10-25
相关资源
最近更新 更多