MySQL中的已知问题
节列出了最新版本的MySQL中的已知问题。
有关特定于平台的问题的信息,请和“调试和移植MySQL”中的安装和移植说明。
已知以下问题:
- 的子查询优化
IN效果不如=。 - 即使您使用
lower_case_table_names=2(使MySQL能够记住用于数据库和表名的大小写),MySQL也不会记住该函数DATABASE()或各种日志中的数据库名的大小写(在不区分大小写的系统上)。 - 删除
FOREIGN KEY约束在复制中不起作用,因为约束在从属服务器上可能具有其他名称。 REPLACE(以及LOAD DATA该REPLACE选项)不会触发ON DELETE CASCADE。DISTINCT如果您不使用全部列表,而是仅使用列表中的那些列,则withORDER BY不能在内部GROUP_CONCAT()使用DISTINCT。- 在十进制或字符串列中插入大整数值(介于2 63和2 64-1之间)时,会将其作为负值插入,因为该数字是在带符号整数上下文中求值的。
 使用基于语句的二进制日志记录,主数据库将执行的查询写入二进制日志。这是一种非常快速,紧凑且有效的日志记录方法,在大多数情况下均可完美运行。但是,如果查询的设计方式不确定,则数据修改是不确定的(通常不建议这样做,即使是在复制之外),也可能使主服务器和从服务器上的数据变得不同。
例如:
CREATE TABLE ... SELECT或在列INSERT ... SELECT中插入零或NULL值的语句AUTO_INCREMENT。DELETE如果要从具有ON DELETE CASCADE属性的外键的表中删除行。REPLACE ... SELECT,INSERT IGNORE ... SELECT如果插入的数据中有重复的键值。
当且仅当前面的查询没有
ORDER BY保证确定性顺序的子句时。例如,对于
INSERT ... SELECTnoORDER BY,SELECT可能会以不同顺序返回行(这导致行具有不同的等级,因此在AUTO_INCREMENT列中获得不同的数字),这取决于优化器在主服务器和从属服务器上所做的选择。仅在以下情况下,对主服务器和从服务器进行的查询优化不同:
- 该表使用与主服务器上不同的存储引擎存储。(可以在主服务器和从服务器上使用不同的存储引擎。例如,可以
InnoDB在主服务器MyISAM上使用,但如果从服务器上的可用磁盘空间较少,则可以在从服务器上使用。) - MySQL缓冲区大小(
key_buffer_size,等等)在主服务器和从服务器上不同。 - 主服务器和从服务器运行不同的MySQL版本,并且这些版本之间的优化器代码不同。
 
此问题也可能影响使用mysqlbinlog | mysql进行数据库还原。
避免此问题的最简单方法是
ORDER BY在上述不确定性查询中添加一个子句,以确保始终以相同的顺序存储或修改行。使用基于行或混合的日志记录格式也可以避免此问题。- 如果未使用启动选项指定文件名,则日志文件名基于服务器主机名。如果将主机名更改为其他名称,要保留相同的日志文件名,必须显式使用诸如的选项。请参见“服务器命令选项”。或者,重命名旧文件以反映您的主机名更改。如果这些是二进制日志,则必须编辑二进制日志索引文件,并在那里也修复二进制日志文件的名称。(对于从属服务器上的中继日志也是如此。)
--log-bin=old_host_name-bin - mysqlbinlog不会删除
LOAD DATA语句后剩余的临时文件。请参见“mysqlbinlog 处理二进制日志文件的实用程序”。 RENAME不适TEMPORARY用于表或表中使用的MERGE表。- 使用时
SET CHARACTER SET,不能在数据库,表和列名称中使用翻译的字符。 - 在此之前的MySQL 8.0.17,你不能使用
_或%用ESCAPE在LIKE ... ESCAPE。 max_sort_length比较数据值时,服务器仅使用前几个字节。这意味着值不能被可靠地在使用GROUP BY,ORDER BY或DISTINCT如果它们仅在第一后不同max_sort_length字节。要解决此问题,请增加变量值。默认值为max_sort_length1024,可以在服务器启动时或在运行时更改。- 数值计算使用
BIGINT或DOUBLE(通常都是64位长)进行。您获得哪种精度取决于功能。一般的规则是,位功能与执行BIGINT精度,IF()并ELT()用BIGINT或DOUBLE精度,其余与DOUBLE精度。如果无符号的long long值解析为大于63位(922337203685477575807),而不是位字段,则应尽量避免使用它们。 - 最多可以有255个
ENUM和SET列在一个表中。 - 在
MIN(),MAX()和其他聚合函数中,MySQL当前根据字符串值而不是字符串在集合中的相对位置来比较ENUM和SET列。 在一条
UPDATE语句中,列从左到右更新。如果引用更新的列,则会获得更新的值,而不是原始值。例如,下面的语句递增KEY的2,不是1:mysql>
UPDATE tbl_nameSET KEY =KEY +1,KEY =KEY +1;您可以在同一查询中引用多个临时表,但是不能多次引用任何给定的临时表。例如对于以下不起作用:
mysql>
SELECT *FROM temp_table, temp_tableAS t2; ERROR 1137: Can't reopen table: 'temp_table'在联接
DISTINCT中使用“隐藏”列时,优化器的处理方式可能与未使用时不同。在联接中,隐藏列被计为结果的一部分(即使未显示),而在常规查询中,隐藏列不参与DISTINCT比较。例如:
SELECT DISTINCT mp3idFROM band_downloadsWHERE userid = 9ORDER BY idDESC ;和
SELECT DISTINCT band_downloads.mp3idFROM band_downloads,band_mp3WHERE band_downloads.userid = 9 AND band_mp3.id = band_downloads.mp3idORDER BY band_downloads.idDESC ;在第二种情况下,您可能在结果集中得到两个相同的行(因为隐藏
id列中的值可能不同)。请注意,这仅适用
ORDER BY于结果中没有列的查询。- 如果
PROCEDURE对返回空集的查询执行,则在某些情况下PROCEDURE不会转换列。 - 类型表的创建
MERGE不会检查基础表是否为兼容类型。 - 如果用于
ALTER TABLE向UNIQUE表中使用的MERGE表添加索引,然后在表上添加普通索引MERGE,则如果表中存在旧的非UNIQUE键,则表的键顺序会有所不同。这是因为ALTER TABLE将UNIQUE索引放在普通索引之前,以便能够尽早检测到重复的键。 
