MySQL前缀索引和覆盖索引(完整索引)

时间:2017-06-12 02:23:40

标签: mysql indexing

当我使用mysql-5.7.17时,我发现了一些东西。 我使用Innodb和charst:utf8。

覆盖索引表架构:

CREATE TABLE test_table ( c_pk varchar(20) NOT NULL DEFAULT '', c_default varchar(32) DEFAULT NULL, c_notnull varchar(20) NOT NULL, PRIMARY KEY (c_pk), KEY IDX_test_table (c_notnull) ) ENGINE=InnoDB DEFAULT CHARSET=utf8

前缀索引表架构:

CREATE TABLE ntable ( c_pk varchar(20) NOT NULL DEFAULT '', c_default varchar(32) DEFAULT NULL, c_notnull varchar(20) NOT NULL, PRIMARY KEY (c_pk(10)), KEY IDX_test_table (c_notnull(10)) ) ENGINE=InnoDB DEFAULT CHARSET=utf8

将相同数据插入ntable和test_table (数据有数字和多字节字符:ex - 123,한글) 当我执行select查询时:SELECT * FROM ntable WHERE c_notnull LIKE'윤선중윤선중윤선중윤선중윤선중윤선중%';

表结果是不同的。 选择数据相同但顺序不同。

最初MySQL Prefix索引和Covering索引(Full index)结果不同??

1 个答案:

答案 0 :(得分:0)

如果没有ORDER BY,引擎可以按照自己选择的顺序自由发送行。要了解结果可能的顺序,我们需要深入了解实现:

在第一种情况下,KEY IDX_test_table (c_notnull)是由c_notnull首先排序的BTree,然后由c_pk排序,因为PRIMARY KEY会隐式附加到每个辅助密钥。

在第二种情况下,索引实际上是(LEFT(c_notnull, 10), c_pk)。 10日之后的字符不参与订单。

尝试这些以查看我的分析是否正确:

SELECT ... ORDER BY c_notnull, c_pk;            -- expect it to match case 1
SELECT ... ORDER BY LEFT(c_notnull, 10), c_pk;  -- expect it to match case 2

"前缀"非常罕见。索引是有用的。我建议您避免使用它,除非c_notnull太长(例如,TEXT)以允许完整索引。

当订单重要时,请使用ORDER BY