MySQL:对太长而无法索引的列进行高效查询
在我的MySQL数据库中,我有一个字符串列(例如,一个SHA散列),它增长太长,无法在上面放置索引。如何对该列运行高效查询MySQL:对太长而无法索引的列进行高效查询,mysql,sql,Mysql,Sql,在我的MySQL数据库中,我有一个字符串列(例如,一个SHA散列),它增长太长,无法在上面放置索引。如何对该列运行高效查询 我可以在列的第一个N字符上放置一个索引,但是使用这个“部分”索引的查询是什么样子的呢 我可以创建一个包含N个字符的第二列,并在该列上放置一个完整的索引,作为“部分”索引的替代。然后,我将查询、获取一条或多条记录,并在内存中执行过滤的最后一步 我可以用,但我需要用MyISAM。MyISAM不支持酸度,因此不支持,谢谢 在MySQL中实现这一点的正确方法是什么 问题不在于减
- 我可以在列的第一个
字符上放置一个索引,但是使用这个“部分”索引的查询是什么样子的呢N
- 我可以创建一个包含
个字符的第二列,并在该列上放置一个完整的索引,作为“部分”索引的替代。然后,我将查询、获取一条或多条记录,并在内存中执行过滤的最后一步李>N
- 我可以用,但我需要用MyISAM。MyISAM不支持酸度,因此不支持,谢谢
create table fingerprinted_item (
type varchar (512) not null,
fingerprint varchar (512) not null,
primary key (fingerprint, type)
);
-- Then there may be a child table.
MySQL说:
[42000][1071] Specified key was too long; max key length is 767 bytes
在其他服务器上,最大密钥长度为1000字节。
试试这个:
ALTER TABLE `mytable` ADD UNIQUE ( yourcolumn(1000))
播放最后一个参数。
试试这个:
ALTER TABLE `mytable` ADD UNIQUE ( yourcolumn(1000))
使用最后一个参数。真正的问题可能是对指纹列使用
VARCHAR
。当使用utf8字符编码时,MySQL强制执行“最坏情况”并计算每个字符的3个字节
将其更改为1字节编码(比如拉丁1),或者改用VARBINARY
类型:
create table fingerprinted_entry
( type varchar (128) not null,
fingerprint varbinary (512) not null,
PRIMARY KEY(type, fingerprint)) ENGINE InnoDB; -- no error here
如果必须超出每个前缀767字节的限制,则必须在创建索引时明确声明:
create table fingerprinted_entry
( type varchar (128) not null,
fingerprint varbinary (2048) not null, -- 2048 bytes
PRIMARY KEY(type, fingerprint(767))) ENGINE InnoDB; -- only the first 767 bytes of fingerprint are stored in the index
真正的问题可能是对指纹列使用
VARCHAR
。当使用utf8字符编码时,MySQL强制执行“最坏情况”并计算每个字符的3个字节
将其更改为1字节编码(比如拉丁1),或者改用VARBINARY
类型:
create table fingerprinted_entry
( type varchar (128) not null,
fingerprint varbinary (512) not null,
PRIMARY KEY(type, fingerprint)) ENGINE InnoDB; -- no error here
如果必须超出每个前缀767字节的限制,则必须在创建索引时明确声明:
create table fingerprinted_entry
( type varchar (128) not null,
fingerprint varbinary (2048) not null, -- 2048 bytes
PRIMARY KEY(type, fingerprint(767))) ENGINE InnoDB; -- only the first 767 bytes of fingerprint are stored in the index
你说的“长得太长而无法建立索引”是什么意思?根据谁的说法?@alexn:为了便于讨论,一个512个字符的安全哈希,可能是SHA,可能是其他东西,超过了索引大小的限制。顺便说一句,表中的字符集是UTF-8(如果MySQL实际存储在类似UCS-2的内容中,则可能会导致MySQL假定每个字符有几个字节)。您能否提供关于“字符串列太长”的更多信息,因为它的最大长度为1000字节,并且可能会增长到3072字节。SHA哈希相当长…@AndyLester:太长了,MySQL抱怨它不能放索引,因为索引的字节限制(即使这是一个varchar)已经超过了。@MihaiDanila 512字节远远低于MyISAM和InnoDB的最大索引大小。您能显示导致问题的语句和相应的错误消息吗?您所说的“增长太长而无法放置索引”是什么意思?根据谁的说法?@alexn:为了便于讨论,一个512个字符的安全哈希,可能是SHA,可能是其他东西,超过了索引大小的限制。顺便说一句,表中的字符集是UTF-8(如果MySQL实际存储在类似UCS-2的内容中,则可能会导致MySQL假定每个字符有几个字节)。您能否提供关于“字符串列太长”的更多信息,因为它的最大长度为1000字节,并且可能会增长到3072字节。SHA哈希相当长…@AndyLester:太长了,MySQL抱怨它不能放索引,因为索引的字节限制(即使这是一个varchar)已经超过了。@MihaiDanila 512字节远远低于MyISAM和InnoDB的最大索引大小。你能展示导致问题的陈述和相应的错误信息吗?啊,这证实了我所担心的。它在内部以某种稀疏格式存储Unicode,很快就会消耗掉字节。您建议使用一个部分索引,但现在讨论剩下的部分:如何编写一个查询使该索引生效?我是否使用MySQL子字符串函数?@MihaiDanila:当您基于列进行操作时,索引将始终“启动”,就像它不是部分索引一样。从技术上讲,它不会强制列在前n个字符之外是唯一的。(您应该将varbinary用于指纹等,否则默认情况下也会得到不区分大小写的比较)@Kris:因此,如果我有一个两个字符的列,第一个字符上有一个索引,并且我的select显示
,其中myColumn='ab'
,然后MySQL将使用索引查找所有以a
开头的行,然后逐一查找ab
?@MihaiDanila:yes。据我所知,这与我所观察到的一致。啊,这证实了我所担心的。它在内部以某种稀疏格式存储Unicode,很快就会消耗掉字节。您建议使用一个部分索引,但现在讨论剩下的部分:如何编写一个查询使该索引生效?我是否使用MySQL子字符串函数?@MihaiDanila:当您基于列进行操作时,索引将始终“启动”,就像它不是部分索引一样。从技术上讲,它不会强制列在前n个字符之外是唯一的。(您应该将varbinary用于指纹等,否则默认情况下也会得到不区分大小写的比较)@Kris:因此,如果我有一个两个字符的列,第一个字符上有一个索引,并且我的select显示,其中myColumn='ab'
,然后MySQL将使用索引查找所有以a
开头的行,然后逐一查找ab
?@MihaiDanila:yes。据我所知,这与我观察到的一致。改变编码不是一个选择