全文索引和复合索引以及它们如何影响查询

2024-04-18

只是说我有一个查询如下..

SELECT 
    name,category,address,city,state
FROM
    table
WHERE 
    MATCH(name,subcategory,category,tag1) AGAINST('education')
AND 
    city='Oakland'
AND
    state='CA' 
LIMIT
    0, 10;

..我有一个fulltext索引为name,subcategory,category,tag1 and a composite索引为city,state;这对于这个查询来说足够好了吗?只是想知道混合额外的东西时是否需要额外的东西AND当使用带有 MATCH/AGAINST 的全文索引时。

Edit:我想要了解的是,查询中但未在所选索引(全文索引)中建立索引的附加列会发生什么情况,上面的示例是city and state。 MySQL 现在如何找到这些匹配的行,因为它不能使用两个索引(或者可以?) - 所以,基本上,我试图了解 MySQL 如何查找数据最佳地对于不在所选全文索引中的列,如果有什么我可以或should做优化查询。


如果我理解你的问题,你就会知道 MATCH AGAINST 使用你的 FULLTEXT 索引,并且你想知道 MySQL 如何应用 WHERE 子句的其余部分(即它是否执行表扫描或索引查找)。

这是我对您的表的假设:它在某些 id 列和 FULLTEXT 索引上有一个主键。

所以首先,MySQL 将never对城市/州 WHERE 子句使用 FULLTEXT 索引。为什么?因为 FULLTEXT 索引仅适用于 MATCH AGAINST。看here http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html在第一组项目符号(不是目录项目符号)之后的段落中。

EDIT:在您的情况下,假设您的表不仅有 10 行,MySQL 将为您的 MATCH AGAINST 应用 FULLTEXT 索引,然后对这些结果进行表扫描以应用城市/州 WHERE。

那么如果将 BTREE 索引添加到城市和州会怎样呢?

CREATE INDEX city__state ON table (city(10),state(2)) USING BTREE;

那么MySQL只能用one该查询的索引,因为它是一个简单的选择。它会either使用全文orBTREE。请注意,当我说一个索引时,我指的是一个索引定义,而不是多部分索引中的一列。无论如何,这就引出了一个问题:哪一个does it use?

这取决于表格分析。 MySQL 将尝试estimate(基于最后一个 OPTIMIZE TABLE 的表统计信息)哪个索引将修剪最多的记录。如果城市/州 WHERE 使您减少到 10 条记录,而 MATCH AGAINST 只能使您减少到 100 条记录,那么 MySQL 将使用 city__state 索引first对于城市/州 WHERE,然后对 MATCH AGAINST 进行表扫描。

另一方面,如果 MATCH_AGAINST 让您减少到 10 条记录,而城市/州 WHERE 让您减少到只有 1000 条记录,那么 MySQL 将首先应用 FULLTEXT 索引,然后对城市和州进行表扫描。

底线是基数你的索引。本质上,将进入索引的值有多独特?如果表中的每条记录都将城市设置为奥克兰,那么它不是一个非常唯一的键,因此城市 = '奥克兰'并没有真正为您减少那么多记录数量。在这种情况下,我们说您的 city__state 索引有低基数.

因此,如果您的 FULLTEXT 索引中 90% 的单词是“John”,那么出于完全相同的原因,这对您也没有多大帮助。

如果你能负担得起空间和 UPDATE/DELETE/INSERT 开销,我建议添加 BTREE 索引并让 MySQL 决定他想要使用哪个索引。根据我的经验,他通常能很好地挑选合适的人选。

我希望这能回答你的问题。

EDIT:顺便说一句,请确保为 BTREE 索引选择正确的大小(在我的示例中,我选择了 city 中的前 10 个字符)。这显然对基数产生了巨大影响。如果您选择 city(1),那么显然您将获得比选择 city(10) 更低的基数。

EDIT2:MySQL 的索引修剪最多记录的查询计划(估计)就是您在 EXPLAIN 中看到的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

全文索引和复合索引以及它们如何影响查询 的相关文章

  • 创建用于存储高尔夫球成绩的可扩展数据库架构

    我正在尝试设计一个数据库来存储我所有的朋友和我的高尔夫球成绩 您可能知道 高尔夫得分由 18 洞的个人得分组成 我可以想到两种设计模式的方法 创建一个表 每个洞有一列 例如 h1 到 h18 该表具有引用其他表的 FK player id
  • 有没有办法从 MySQL 的列中提取与正则表达式匹配的文本?

    例如 如果特定列中的所有条目都具有 a z 0 9 形式 如何仅提取前导字母 以便 asdf123 和 as3456 分别返回 asdf 和 as 这对于 mysql 正则表达式功能来说是不可能的 除非安装一些似乎是为此设计的 udf 从技
  • 数据包无序。得到:80 预期:0 node.js

    这是我的 非常简单 代码 var connection mysql createConnection infosDB connection connect connection query SELECT FROM action functi
  • MySQL:如何获取上次更新的更改

    我正在使用 MySQL 和 PHP 开发数据库应用程序 此时我正在尝试获取上次更新引起的更改 我解决问题的第一个方法是 使用 SELECT 获取 旧 状态 使用 UPDATE 进行更改 使用 SELECT 获取 新 状态 将数组与 php
  • 比较 PHP 中的 unix 时间戳 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 在 PHP 中我有 diff abs
  • MySQL按总和连接表问题

    我在连接表时遇到问题 以下是示例表 表A 30行 ID Name Description 1 Type Unicode Art 2 Header Spreadsheet 3 Auto Align Off 表B 100行 ID Name De
  • 如何在 MySql Workbench 中禁用 INVISIBLE 索引选项?

    我刚刚安装了MySqlWorkbench我发现了实施INVISIBLE index所描述的here https dev mysql com doc refman 8 0 en invisible indexes html 我想禁用此功能 因
  • Mysql 连接到服务器:用户 root@localhost 的访问被拒绝

    edit9 是否有可能我只是缺少文件夹的一些权限 我真的非常非常感谢更多的建议 edit3 由于这篇文章没有得到足够的回复 而且这绝对是至关重要的 我尽快完成这件事 我重建了我的帖子以显示我认为到目前为止我已经扣除的内容 注意 通过许多不同
  • 更新或插入 MySQL Python

    如果记录已存在 我需要更新一行 如果不存在 我需要创建一个新记录 我理解 ON DUPLICATE KEY 将使用 MYSQLdb 完成此操作 但是我无法使其正常工作 我的代码如下 cursor database cursor cursor
  • PDO 库比本机 MySQL 函数更快吗?

    我已经阅读了几个与此相关的问题 但我担心它们可能已经过时 因为自这些问题得到解答以来 更新版本的 PDO 库已经发布 我编写了一个 MySQL 类 它构建查询并转义参数 然后根据查询返回结果 目前这个类正在使用内置的mysql函数 我很清楚
  • 规范“毒”方式真的值得吗? (3NF)

    我正处于数据库设计的早期阶段 所以还没有最终的结果 并且我正在为具有可选标签的线程使用 TOXI 3表设计 但我忍不住觉得加入是并不是真的必要 也许我只需要依赖我的简单标签列posts我可以在其中存储类似 varchar 的表
  • 如何使用 pandas 对一系列值进行编码

    我有一个 pandas 数据框并且有一列age 我想将其编码为按特定范围分隔的分类值 例如 15岁以下的年龄应为0 15到30之间的年龄应更改为1等等 我找到了这种方法来做到这一点 在经历了关于使用的巨大困惑之后 and and age X
  • 安全转义表名/列名

    我在 php 中使用 PDO 因此无法使用准备好的语句转义表名或列名 以下是我自己实现它的万无一失的方法 tn str replace REQUEST tn column str replace REQUEST column sql SEL
  • BigDecimal 的 JPA @Size 注释

    我该如何使用 SizeMySQL 的注释DECIMAL x y 列 我在用着BigDecimal 但是当我尝试包括 Size max它不起作用 这是我的代码 Size max 7 2 Column name weight private B
  • 使用 Laravel Fluent 查询生成器从多个表中进行选择

    我正在重写一些 PHP MySQL 来与 Laravel 一起使用 我想做的一件事是使数据库查询更加简洁使用 Fluent 查询生成器 http laravel com docs database fluent但我有点迷失 SELECT p
  • 使用 PHP 和 jSON 从 MySQL 获取 UIImage

    我正在开发一个小型新闻阅读器 它通过对 URL 执行 POST 请求来从网站检索信息 响应是一个带有未读新闻的 JSON 对象 例如 应用程序上的最新新闻的时间戳为 2013 03 01 当用户刷新表时 它会发布 domain com ap
  • Mysql:计算访问频率

    我有这张桌子 CREATE OR REPLACE TABLE hits ip bigint page VARCHAR 256 agent VARCHAR 1000 date datetime 我想计算每个页面的 googlebot 访问频率
  • MySQL 查询获取每小时计数

    我需要统计每小时发生的操作次数 我的数据库按操作的时间戳保存日志 我明白我可以做一个 SELECT table time COUNT table time from table t group by t time 然而 也有一段时间没有采取
  • 测验程序的 MySql 数据库设计

    我目前正在开发一个项目 主要是创建一个测验应用程序 它将能够进行包含 10 到 20 个问题的多项选择题或简答题的测验 它需要能够根据正确答案检查用户的答案 然后对用户的答案进行评分 稍后 我可能会实现一个后端功能来在线创建测验 但现在我将
  • 未找到教义列:1054“字段列表”中未知列“s.features”

    我在站点表中添加了一个新列 features 并使用 Doctrine 重新生成了模型 此代码导致错误 siteTable Doctrine Core getTable Site site siteTable gt findOneByNam

随机推荐