MySQL | index FULLTEXT 与 index PRIMARY KEY used in a WHERE like Query

问题描述 投票:0回答:1

问题

有一个主键为

varchar
的表,用于查找带有
WHERE column like 'some_string%'
的大量数据(数百万)和大量请求(每秒1000个)我需要提高性能这样的查询

问题

  • 如果 also
    FULLTEXT
    类型的索引,那么主键列会工作得更好吗?
  • 是否有更快的方法来查找给出以下情况的记录,或者这很好吗?

注意: 已经在评论区指出: “你为什么不尝试一下,看看你是否能获得任何性能提升?”

我最终也会在场外尝试一下,但问题的目的(并在 StackOverflow 中询问)不仅仅是“这会运行得更快吗”? 但也有一些关于该主题经验的其他意见,这可能会告诉我是否有用,不会做任何改变,危险,更好的方法等。?

要运行实际测试和基准测试,有很多因素并且非常耗时,希望知道答案的人会告诉我。为了真正超越性能来测试某些东西,尤其是在这种性质上,您需要在不同的环境中进行测试,使用大量的测试数据并测试不同的场景。不足以在本地进行测试,无论出于何种原因,您都可能得到错误的结果,或者这可能会在未来引起我不知道的问题

场景

送这张桌子

create table book
(
    title       varchar(100)                       not null,
    author      varchar(20)                        not null,   
    created     datetime default CURRENT_TIMESTAMP not null,
    primary key (title, author)
);

我们插入一些测试数据

insert into book (author, title) values
    ('JohnDoe', 'bookSummer_1'),
    ('JohnDoe', 'bookSummer_2'),
    ('JohnDoe', 'bookSummer_3'),
    ('JohnDoe', 'bookSummer_4'),
    ('JohnDoe', 'bookWinder_1'),
    ('JohnDoe', 'bookWinder_2'),
    ('JohnDoe', 'bookWinder_3'),
    ('JohnDoe', 'bookWinder_4')

然后,我们通过它的前缀来抓取书名

SELECT author, title from book WHERE author='JohnDoe' and title like 'bookSummer_%';

现在,假设一位作者有数百万本不同的书,我们的标题前缀可能长达 100 个字符。如您所见,

title
列已经是一个
PRIMARY KEY
添加列
title
类型的附加索引
FULLTEXT
是有益的(并且可能更改查询?

所以我的意思是这样添加

ALTER TABLE book ADD FULLTEXT INDEX `title_fulltext_index` (`title`);
mysql performance select indexing full-text-search
1个回答
1
投票

根据您的具体查询,例如前缀搜索 (

like 'somestring%'
),全文索引没有意义。

如果您在句子中间查找单词,则全文索引可以提高性能,例如

'some text somestring'
。一个普通的索引不会索引
somestring
,所以要找到它,你必须翻遍整个表。全文索引将索引每个单词,因此您可以通过(快速)索引查找找到
'some'
'text'
'somestring'

还有一些额外的步骤:全文索引不能与另一个索引一起使用,所以如果你找到标题并想验证作者是否匹配,你必须从表中读取实际行。

如果您改为使用主键查找标题,那么您已经从表中读取了行(因为读取主键意味着读取表,至少对于 InnoDB 而言),所以您已经在那里了。

甚至很难想出全文索引对您的情况会更快的理论场景。一种情况可能是,如果您的表非常大,最好大到无法放入内存,而全文索引很小并且可以保存在缓存中,而您要查找不存在的条目。然后全文索引可以给你答案而不需要缓慢的磁盘读取。但即使那样,也可能有更好的方法来改进您的设置。

顺便说一下,查询的最佳索引 (

where author = 'string' and title like 'otherstring%'
) 是一个索引
(author, title)
,例如列的顺序与主键中的顺序不同。这是因为当您使用第一列进行部分匹配时,索引查找不能再使用第二列,但如果第一列的比较是“=”,它可以使用两列。想象一下,例如按“名字,名字”排序的电话簿。如果我让你找到名字为“Federico”而姓氏为“B%”的每个人,名字并不会减少你必须查看的条目数量(例如,你将阅读条目的所有名字以“B”开头)。对于按“名字,名字”排序的电话簿,您可以跳过所有不是“Federico”的名字,以及所有不以“B”开头的姓氏。

如果它对您的数据产生影响,尤其是如果它产生的影响足以抵得上索引所需的额外资源(例如磁盘空间、更新时间),那么您就必须进行测试。

© www.soinside.com 2019 - 2024. All rights reserved.