MySQL:对太长而无法索引的列进行高效查询

MySQL:对太长而无法索引的列进行高效查询,mysql,sql,Mysql,Sql,在我的MySQL数据库中,我有一个字符串列(例如,一个SHA散列),它增长太长,无法在上面放置索引。如何对该列运行高效查询 我可以在列的第一个N字符上放置一个索引,但是使用这个“部分”索引的查询是什么样子的呢 我可以创建一个包含N个字符的第二列,并在该列上放置一个完整的索引,作为“部分”索引的替代。然后,我将查询、获取一条或多条记录,并在内存中执行过滤的最后一步 我可以用,但我需要用MyISAM。MyISAM不支持酸度,因此不支持,谢谢 在MySQL中实现这一点的正确方法是什么 问题不在于减

在我的MySQL数据库中,我有一个字符串列(例如,一个SHA散列),它增长太长,无法在上面放置索引。如何对该列运行高效查询

  • 我可以在列的第一个
    N
    字符上放置一个索引,但是使用这个“部分”索引的查询是什么样子的呢
  • 我可以创建一个包含
    N
    个字符的第二列,并在该列上放置一个完整的索引,作为“部分”索引的替代。然后,我将查询、获取一条或多条记录,并在内存中执行过滤的最后一步
  • 我可以用,但我需要用MyISAM。MyISAM不支持酸度,因此不支持,谢谢
在MySQL中实现这一点的正确方法是什么

问题不在于减小列的大小,也不在于在配置了过短键长的数据库时重新配置数据库。它是关于毫无痛苦地利用部分索引或类似的东西,最好不要给应用程序增加负担或弹出额外的列

在我的特殊情况下,我在UTF8表的两列上寻找复合键:

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。据我所知,这与我观察到的一致。改变编码不是一个选择