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 ... SELECT
noORDER 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_length
1024,可以在服务器启动时或在运行时更改。- 数值计算使用
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
索引放在普通索引之前,以便能够尽早检测到重复的键。