MySQL-索引创建问题-区别在哪里?

时间:2018-09-19 11:10:33

标签: mysql

我有两个MySQL数据库实例,比如说:TST和DEV。

TST:

mysql --version
mysql  Ver 14.14 Distrib 5.6.40, for Linux (x86_64) using  EditLine wrapper

DEV:

mysql --version
mysql  Ver 14.14 Distrib 5.6.41, for Linux (x86_64) using  EditLine wrapper

两种环境下的版本几乎相同。

两个实例上的数据库具有相同的架构和相同的数据。

问题表的结构如下:

CREATE TABLE `searchItem` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `type` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
  `dataType` varchar(4) COLLATE utf8_unicode_ci NOT NULL,
  `value` varchar(1024) COLLATE utf8_unicode_ci NOT NULL,
  `creationTime` datetime NOT NULL,
  `modificationTime` datetime NOT NULL,
  `contentId` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `IDX_36F9E76573A18A3B` (`contentId`),
  KEY `content_type` (`contentId`,`type`),
  CONSTRAINT `FK_36F9E76573A18A3B` FOREIGN KEY (`contentId`) REFERENCES `content` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23518 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

现在我想在列值(1024)上添加索引。我知道在我的情况下,索引大小限制为255。

在DEV上:

CREATE INDEX value_type ON searchItem (value, type);
Query OK, 0 rows affected, 1 warning (0.30 sec)

现在我有:

CREATE TABLE `searchItem` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `type` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
  `dataType` varchar(4) COLLATE utf8_unicode_ci NOT NULL,
  `value` varchar(1024) COLLATE utf8_unicode_ci NOT NULL,
  `creationTime` datetime NOT NULL,
  `modificationTime` datetime NOT NULL,
  `contentId` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `IDX_36F9E76573A18A3B` (`contentId`),
  KEY `content_type` (`contentId`,`type`),
  KEY `value_type` (`value`(255),`type`),
  CONSTRAINT `FK_36F9E76573A18A3B` FOREIGN KEY (`contentId`) REFERENCES `content` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23518 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

因此它会自动将索引切为最大大小(255),这对我来说是预期的行为。

但在TST上

CREATE INDEX value_type ON searchItem (value, type);
ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes

在my.cnf文件中没有发现任何差异。

[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock

[isamchk]
key_buffer_size = 16M

[mysqld]
basedir = /usr
bind-address = 0.0.0.0
character-set-server = utf8
datadir = /var/lib/mysql
default_storage_engine = InnoDB
expire_logs_days = 10
init-connect = SET NAMES utf8
innodb_file_per_table = 1
key_buffer_size = 16M
log-error = /var/log/mysql/error.log
max_allowed_packet = 128M
max_binlog_size = 100M
max_connections = 151
myisam_recover = BACKUP
pid-file = /var/run/mysqld/mysqld.pid
port = 3306
query_cache_limit = 1M
query_cache_size = 16M
skip-external-locking
socket = /var/run/mysqld/mysqld.sock
ssl = false
ssl-ca = /etc/mysql/cacert.pem
ssl-cert = /etc/mysql/server-cert.pem
ssl-key = /etc/mysql/server-key.pem
thread_cache_size = 8
thread_stack = 256K
tmpdir = /tmp
user = mysql

[mysqld_safe]
log-error = /var/log/mysql/error.log
nice = 0
socket = /var/run/mysqld/mysqld.sock

[mysqldump]
max_allowed_packet = 128M
quick
quote-names

编辑:

问题的实质:

在DEV上:

CREATE INDEX value_type ON searchItem (value, type);
Query OK, 0 rows affected, 1 warning (0.30 sec)

但在TST上

CREATE INDEX value_type ON searchItem (value, type);
ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes

问题是为什么它在每种环境下的行为都不同?是否有任何配置参数可以对此负责?

2 个答案:

答案 0 :(得分:0)

您使用哪种类型的引擎?在MySQL版本5.6(及更低版本)中,InnoDB表的前缀限制为767个字节。 MyISAM表的长度为999个字节(或1000,记不清了)

您可以切换引擎类型或升级到MySQL 5.7,这会限制到3K

答案 1 :(得分:0)

这是Strict SQL Mode的作用:

  

从MySQL 5.6.11开始,严格模式在尝试创建超出最大密钥长度的密钥时会产生错误。以前,这会导致警告并把密钥截断为最大密钥长度(与未启用严格模式时相同)。

在没有严格模式的情况下,允许MySQL调整值使其适合,然后将错误减少为警告;这是您在运行语句时收到的警告。

您可以使用select @@sql_mode检查当前的sql模式(TST服务器可能包含例如STRICT_TRANS_TABLES,而DEV不包含)。可以在运行时在全局和每个会话期间更改该设置,因此可能有人或某些更改了该设置。