MySQL 模糊搜索的 Big-O
Big-O of MySQL Fuzzy Search
MySQL 模糊搜索的 Big-O 是什么?它是否因索引类型而异,如果是,哪种表现最好?
例如SELECT * FROM foo WHERE field1 LIKE '%ello Wo%';
我不确定底层数据类型,它拥有什么样的魔力。像 trie (https://en.wikipedia.org/wiki/Trie) 这样的东西对于最后模糊的搜索来说会很好,例如LIKE 'Hello Wo%'
.
我猜 Big-O 是 O(n)
但想确认一下。模糊搜索之间甚至可能存在差异,例如%ello Wo%
对比 Hello W%
对比 %lo World
对比 %ell%o%W%or%
是否有不同的索引方法可以提供更好的性能?如果是,对于特定情况,能否分享一下?
带前导通配符
MySQL 将
- 扫描 table 中的所有行(不是索引)。这称为 "table scan"。 (假设没有进行其他过滤。)
- 对于每一行,扫描有问题的列以获得
LIKE
;
- 传递未过滤掉的行。
大部分时间花在步骤 1 上,即 O(N),其中 N 是行数。第 2 步和第 3 步花费的时间少得多。
没有前导通配符
- 对该列使用索引,如果有索引,以限制要搜索的行数。如果您在该列上有一个索引并且说
WHERE col LIKE 'Hello W%'
,它将找到索引中以 Hello W
开头的所有行。它们在索引中是连续的,使这一步更快。
- 对于其中的每一个,进入该行的数据并执行任何其他需要的操作。
有许多变量(缓存、行数、行的随机性等)导致#1 比#2 的成本更高还是更低。但这可能比前导通配符的情况快得多——O(n),其中 n
是以 'Hello W'.
开头的行数
MySQL 模糊搜索的 Big-O 是什么?它是否因索引类型而异,如果是,哪种表现最好?
例如SELECT * FROM foo WHERE field1 LIKE '%ello Wo%';
我不确定底层数据类型,它拥有什么样的魔力。像 trie (https://en.wikipedia.org/wiki/Trie) 这样的东西对于最后模糊的搜索来说会很好,例如LIKE 'Hello Wo%'
.
我猜 Big-O 是 O(n)
但想确认一下。模糊搜索之间甚至可能存在差异,例如%ello Wo%
对比 Hello W%
对比 %lo World
对比 %ell%o%W%or%
是否有不同的索引方法可以提供更好的性能?如果是,对于特定情况,能否分享一下?
带前导通配符
MySQL 将
- 扫描 table 中的所有行(不是索引)。这称为 "table scan"。 (假设没有进行其他过滤。)
- 对于每一行,扫描有问题的列以获得
LIKE
; - 传递未过滤掉的行。
大部分时间花在步骤 1 上,即 O(N),其中 N 是行数。第 2 步和第 3 步花费的时间少得多。
没有前导通配符
- 对该列使用索引,如果有索引,以限制要搜索的行数。如果您在该列上有一个索引并且说
WHERE col LIKE 'Hello W%'
,它将找到索引中以Hello W
开头的所有行。它们在索引中是连续的,使这一步更快。 - 对于其中的每一个,进入该行的数据并执行任何其他需要的操作。
有许多变量(缓存、行数、行的随机性等)导致#1 比#2 的成本更高还是更低。但这可能比前导通配符的情况快得多——O(n),其中 n
是以 'Hello W'.