Mysql:前缀索引与索引

iPh*_*ian 3 mysql indexing innodb

可以像普通索引一样使用mysql前缀索引吗?

如果有一些TEXT列,并且前缀索引的长度为例如1,则查询为:

SELECT * FROM table WHERE textcol = 'ab'

它会给我所有以'a'开头的行还是会检查整列值?

一般来说,我很想知道使用前缀索引时是否有任何警告.不考虑性能,如果任何查询必须以不同方式编写,或者客户端是否必须执行额外逻辑,则更多.

Mic*_*bot 6

如果你想一下,MySQL仍然会给你正确的答案,即使没有索引...它只是不会那么快......所以,是的,你仍然会得到一个正确的答案前缀索引.

性能会降低,因为在将"可能"行与索引匹配后,服务器将转到行数据并进一步根据WHERE子句过滤结果.两个步骤而不是一个,但应用程序无需关心.

需要注意的事实是,优化器不会对某些操作(如排序或分组)使用前缀索引,因为它没有为此目的覆盖足够的列数据.

前缀索引的排序不超出前缀的长度.如果您的查询使用完整索引来查找行,您通常会发现返回的行是按索引顺序隐式排序的.如果您的应用程序需要此行为,那么它当然期望它不应该期望的东西,因为除非您明确指出,否则返回行的顺序是未定义的ORDER BY.在任何查询中都不要依赖巧合行为,因为不仅前缀索引匹配的行不一定是任何特定顺序......但事实上,排序不明确的任何结果集的顺序是主题随时改变.

并且,前缀索引不能用作覆盖索引.覆盖索引是指a中的所有列SELECT恰好包含在一个索引中的情况(加上可选的主键,因为它也总是存在).优化器将直接从索引读取数据,而不是使用索引来标识要在主表数据中查找的行.即使索引不能用于查找匹配的行,优化器也只会对覆盖索引进行全扫描,而不是对整个表进行全扫描,从而节省了I/O和时间.(顺便说一下,这个功能应该足以让您选择所需的列,而不是懒惰SELECT *- 它可能会打开一些更有效的查询计划).前缀索引也不能用于此.

但是除了性能,优化和查询隐含地做你期望的事情(你不应该期待)之外,没有与前缀索引想到的逻辑相关的警告.结果仍然是正确的.

  • 在我对相关问题的回答中,即使前缀长于列中实际存储的最长值,前缀索引也无法用于排序的说明,位于 http://dba.stackexchange.com/a/48104/ 11651。 (2认同)

Ric*_*mes 5

很多时候,“前缀索引”是没有用的。我见过当我认为它可以使用前缀索引时它会忽略它的情况。

如果您的TEXT字段永远不会超过 255 个字符,请将其更改为VARCHAR(255)(或更小);然后使用真实索引,而不是前缀索引。

它会只给我以“a”开头的所有行还是会检查整个列值?

假设您有INDEX(textcol(1)),那么它必须扫描以 开头的所有行,a以查找 的行textcol = 'ab'并仅传送这些行。请注意,这是一个性能问题,而不是正确性问题(正如 @Michaelsqlbot 雄辩地阐明的那样)。