MySQL 在索引中使用自定义字符串比较运算符
Posted
技术标签:
【中文标题】MySQL 在索引中使用自定义字符串比较运算符【英文标题】:MySQL using a custom string comparison operator in Index 【发布时间】:2017-02-22 11:37:04 【问题描述】:我正在寻找一种方法来指定 mysql 索引使用的顺序(使用 MariaDB 10 的 InnoDB 中的 BTREE)。更具体地说,我想创建一个索引,该索引使用类似于以下伪代码的可变长度条目来索引 varchar
列:
-- assume "str" to be the field in question, return values like strcmp
if (len(row1.str) < len(row2.str))
return -1;
else if (len(row1.str) > len(row2.str))
return 1;
else
return row1.str < row2.str;
有没有办法只为一个特定的索引指定这种排序?
【问题讨论】:
【参考方案1】:这样的东西应该有同样的效果:
ORDER BY CHAR_LENGTH(str), str
【讨论】:
我考虑过使用具有类似ORDER BY
子句的物化视图,但这必须在数据库查询中显式使用(读取连接),而拥有索引只会启用查询优化器在我认为合适的时候选择它。【参考方案2】:
https://mariadb.com/kb/en/mariadb/virtual-computed-columns/ --
ALTER TABLE foo ADD COLUMN
for_sorting VARCHAR(...) -- make a little wider than `str`
AS ( -- syntax
CONCAT(
RIGHT(CONCAT('0000', CHAR_LENGTH(str)), 5), -- num sortable as string
':', str ) -- tack on `str` for when len differs
) PERSISTENT -- "indexes can only be based on PERSISTENT virtual columns"
COMMENT "kludge for special indexing"
然后做ORDER BY for_sorting
。
(警告:我没有尝试过,但感觉它会起作用。)
【讨论】:
[In]兼容性说明:这是 MariaDB 特有的功能; MySQL 有类似的东西。 也是一个好主意,但是对于长度为 n 的字符串需要 n + log(n) + 一些恒定的额外空间。最后,我将可能输入的子集转换为整数值,并对意外值进行了硬错误。 因为是PERSISTENT
,所以每个INSERT
(或UPDATE
)计算一次表达式;这是很小的开销。一旦它“持续存在”,ORDER BY
的开销与使用任何其他列进行排序的开销相同。是的,它确实需要额外的磁盘空间,相当于添加一列并为新列建立索引。以上是关于MySQL 在索引中使用自定义字符串比较运算符的主要内容,如果未能解决你的问题,请参考以下文章