mysql前缀索引可以像普通索引一样使用吗?
如果有一些 TEXT
列并且它上面的前缀索引的长度是例如1 并且查询是:
SELECT * FROM table WHERE textcol = 'ab'
它会只给我所有以“a”开头的行还是会检查整个列的值?
一般来说,我很想知道在使用前缀索引时是否有任何注意事项。不考虑性能,更多的是如果任何查询必须以不同的方式编写或者客户端是否必须执行额外的逻辑。
最佳答案
如果你想一想,MySQL 仍然会给你正确的答案,即使没有 索引......它只是不会那么快......所以,是的,你仍然会得到带有前缀索引的正确答案。
性能会降低,因为在将“可能的”行与索引匹配后,服务器将转到行数据并根据 WHERE
子句进一步过滤结果。两步而不是一步,但应用程序无需关心。
注意事项包括这样一个事实,即前缀索引不会被优化器用于某些操作,例如排序或分组,因为它没有为这些目的覆盖足够的列数据。
前缀索引不会超出前缀的长度进行排序。如果您的查询使用完整索引来查找行,您通常会发现返回的行隐式按索引顺序排序。如果您的应用程序期望此行为,那么它当然会期望一些它不应该期望的行为,因为返回行的顺序是未定义的,除非您显式 ORDER BY
。在任何查询中都不要依赖巧合行为,因为不仅前缀索引匹配的行不一定按任何特定顺序......而且实际上任何排序不明确的结果集的顺序都是主题随时更改。
而且,前缀索引不能用作覆盖索引。覆盖索引指的是 SELECT
中的所有列恰好一起包含在一个索引中(加上可选的主键,因为它总是在那里)。优化器将直接从索引中读取数据,而不是使用索引来标识要在主表数据中查找的行。即使无法使用索引查找匹配的行,优化器也只会对覆盖索引进行全扫描,而不是对整个表进行全扫描,从而节省 I/O 和时间。 (顺便说一句,这种能力应该是选择所需列的充分理由,而不是懒惰的 SELECT *
—— 它可能会打开一些更有效的查询计划)。前缀索引也不能用于此。
但是除了性能和优化以及隐式执行您期望的事情(您不应该期望的)的查询之外,没有任何与逻辑相关的关于前缀索引的警告。结果仍然是正确的。
关于Mysql:前缀索引与索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31526618/