有一个主键为
varchar
的表,用于查找带有WHERE column like 'some_string%'
的大量数据(数百万)和大量请求(每秒1000个)我需要提高性能这样的查询
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`);
根据您的具体查询,例如前缀搜索 (
like 'somestring%'
),全文索引没有意义。
如果您在句子中间查找单词,则全文索引可以提高性能,例如
'some text somestring'
。一个普通的索引不会索引somestring
,所以要找到它,你必须翻遍整个表。全文索引将索引每个单词,因此您可以通过(快速)索引查找找到 'some'
、'text'
和 'somestring'
。
还有一些额外的步骤:全文索引不能与另一个索引一起使用,所以如果你找到标题并想验证作者是否匹配,你必须从表中读取实际行。
如果您改为使用主键查找标题,那么您已经从表中读取了行(因为读取主键意味着读取表,至少对于 InnoDB 而言),所以您已经在那里了。
甚至很难想出全文索引对您的情况会更快的理论场景。一种情况可能是,如果您的表非常大,最好大到无法放入内存,而全文索引很小并且可以保存在缓存中,而您要查找不存在的条目。然后全文索引可以给你答案而不需要缓慢的磁盘读取。但即使那样,也可能有更好的方法来改进您的设置。
顺便说一下,查询的最佳索引 (
where author = 'string' and title like 'otherstring%'
) 是一个索引 (author, title)
,例如列的顺序与主键中的顺序不同。这是因为当您使用第一列进行部分匹配时,索引查找不能再使用第二列,但如果第一列的比较是“=”,它可以使用两列。想象一下,例如按“名字,名字”排序的电话簿。如果我让你找到名字为“Federico”而姓氏为“B%”的每个人,名字并不会减少你必须查看的条目数量(例如,你将阅读条目的所有名字以“B”开头)。对于按“名字,名字”排序的电话簿,您可以跳过所有不是“Federico”的名字,以及所有不以“B”开头的姓氏。
如果它对您的数据产生影响,尤其是如果它产生的影响足以抵得上索引所需的额外资源(例如磁盘空间、更新时间),那么您就必须进行测试。