2015-07-20 52 views
2

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

如果有一些TEXT柱和前缀索引上它是例如长度1,查询是:

SELECT * FROM table WHERE textcol = 'ab'

难道只是给我的所有行以“a”或它会检查整个列值?

总的来说,我很好奇,想知道是否使用前缀索引时有什么注意事项。不涉及性能,如果有任何查询需要以不同的方式写入,或者客户端是否必须执行额外的逻辑,则更多。

回答

3

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

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

的注意事项包括前缀索引不会被优化用于一些操作,如排序或分组,因为它不包括足够为这些目的列数据的事实。

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

并且,前缀索引不能被用作覆盖索引。覆盖索引指的是SELECT中的所有列碰巧被包括在一个索引中(可选地,主键,因为它总是存在)的情况。优化器将直接从索引中读取数据,而不是使用索引来标识要在主表数据中查找的行。即使索引不能用于查找匹配的行,优化程序也会仅对覆盖索引进行全面扫描,而不是对整个表进行全面扫描,从而节省I/O和时间。 (顺便提一句,这个功能应该有足够的理由来选择你想要的列,而不是懒惰的SELECT * - 它可能会打开一些更有效的查询计划)。前缀索引也不能用于此。

但是,除了性能和优化和查询,隐式做你期望的事情(你不应该期待),没有注意到与注意前缀索引警告。结果仍然是正确的。

+1

前缀索引不能用于排序的说明,即使前缀长于实际存储在列中的最长值时,也是在我对相关问题的回答中:http://dba.stackexchange.com/a /11651分之48104。 –

2

通常,“前缀索引”是无用的。我曾经看到过当它认为可以使用前缀索引时忽略前缀索引的情况。

如果您TEXT场从未超过255个字符更大,将其更改为VARCHAR(255)(或更小);然后使用一个真正的索引,而不是一个前缀索引。

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

假设你有INDEX(textcol(1))的话,那就必须扫描所有的行与a开始textcol = 'ab'找到行(S)和只提供那些行。请注意,这是一个性能问题,而不是一个正确性问题(正如@Michaelsqlbot雄辩地阐述的那样)。