当我使用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)结果不同??
答案 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
。