本節列出 MySQL 最近版本中的已知問題。
關於特定平台的問題,請參閱第 2.1 節「一般安裝指南」和第 7.9 節「除錯 MySQL」中的安裝和除錯說明。
以下是已知的問題
對於
IN
的子查詢最佳化效果不如=
。即使您使用
lower_case_table_names=2
(這會讓 MySQL 記住資料庫和表格名稱使用的大小寫),MySQL 也不會記住DATABASE()
函式或各種記錄檔中資料庫名稱使用的大小寫 (在不區分大小寫的系統上)。刪除
FOREIGN KEY
限制在複寫中不起作用,因為該限制在複本上可能具有其他名稱。如果未使用
DISTINCT
清單中的所有且僅限那些欄位,則DISTINCT
與ORDER BY
在GROUP_CONCAT()
內不起作用。當將一個大整數值 (介於 263 和 264−1 之間) 插入小數或字串欄位時,它會以負值插入,因為該數字是在帶號整數上下文中評估的。
使用以陳述式為基礎的二進位記錄時,來源伺服器會將執行的查詢寫入二進位記錄。這是一種非常快速、簡潔且有效率的記錄方法,在大多數情況下都能完美運作。但是,如果查詢的設計方式導致資料修改不具確定性 (通常不建議這樣做,即使在複寫之外也是如此),來源和複本上的資料可能會變得不同。
例如
將零或
NULL
值插入AUTO_INCREMENT
欄位的CREATE TABLE ... SELECT
或INSERT ... SELECT
陳述式。如果您要從具有
ON DELETE CASCADE
屬性的外部索引的表格中刪除列,則使用DELETE
。如果插入的資料中有重複的索引鍵值,則使用
REPLACE ... SELECT
、INSERT IGNORE ... SELECT
。
只有在前面的查詢沒有保證確定性順序的
ORDER BY
子句時.例如,對於沒有
ORDER BY
的INSERT ... SELECT
,SELECT
可能會以不同的順序傳回列 (這會導致列具有不同的排名,因此在AUTO_INCREMENT
欄位中獲得不同的數字),具體取決於來源和複本上的最佳化工具所做的選擇。只有在以下情況下,查詢在來源和複本上的最佳化方式才會不同
表格在來源上使用的儲存引擎與在複本上不同。(可以在來源和複本上使用不同的儲存引擎。例如,如果複本可用磁碟空間較少,您可以在來源上使用
InnoDB
,但在複本上使用MyISAM
。)來源和複本上的 MySQL 緩衝區大小 (
key_buffer_size
等) 不同。來源和複本執行不同的 MySQL 版本,且這些版本之間的最佳化工具程式碼不同。
此問題也可能會影響使用 mysqlbinlog|mysql 還原資料庫。
避免此問題最簡單的方法是在前面提到的非確定性查詢中新增
ORDER BY
子句,以確保列始終以相同的順序儲存或修改。使用以列為基礎或混合的記錄格式也可以避免這個問題。如果您沒有使用啟動選項指定檔案名稱,則記錄檔名稱會以伺服器主機名稱為基礎。如果您將主機名稱變更為其他名稱,要保留相同的記錄檔名稱,您必須明確使用選項,例如
--log-bin=
。請參閱第 7.1.7 節「伺服器命令選項」。或者,重新命名舊檔案以反映您的主機名稱變更。如果這些是二進位記錄,您也必須編輯二進位記錄索引檔案並修復其中的二進位記錄檔案名稱。(複本上的中繼記錄也是如此。)old_host_name
-binmysqlbinlog 不會刪除
LOAD DATA
陳述式後留下的暫存檔案。請參閱第 6.6.9 節「mysqlbinlog — 處理二進位記錄檔案的公用程式」。RENAME
不適用於TEMPORARY
表格或MERGE
表格中使用的表格。當使用
SET CHARACTER SET
時,您無法在資料庫、表格和欄位名稱中使用已翻譯的字元。伺服器在比較資料值時,僅使用前
max_sort_length
個位元組。這表示如果值只有在前max_sort_length
個位元組之後才有所不同,則這些值無法可靠地用於GROUP BY
、ORDER BY
或DISTINCT
。為了解決此問題,請增加變數值。max_sort_length
的預設值為 1024,可以在伺服器啟動時或執行時進行變更。數值計算使用
BIGINT
或DOUBLE
(兩者通常都是 64 位元長)。您獲得的精確度取決於函數。一般規則是位元函數使用BIGINT
精確度執行,IF()
和ELT()
使用BIGINT
或DOUBLE
精確度,其餘則使用DOUBLE
精確度。如果無號長長整數值解析後大於 63 位元 (9223372036854775807),您應該盡量避免使用這些值,除非它們是用於位元欄位。在
MIN()
、MAX()
和其他聚合函數中,MySQL 目前會依據字串值,而不是依據字串在集合中的相對位置來比較ENUM
和SET
欄位。在
UPDATE
陳述式中,欄位會從左至右更新。如果您參照已更新的欄位,您會取得更新過的值,而不是原始值。例如,以下陳述式會將KEY
遞增2
,而不是1
mysql> UPDATE tbl_name SET KEY=KEY+1,KEY=KEY+1;
您可以在同一個查詢中參照多個暫存資料表,但您不能多次參照任何給定的暫存資料表。例如,以下程式碼無法運作
mysql> SELECT * FROM temp_table, temp_table AS t2; ERROR 1137: Can't reopen table: 'temp_table'
當您在聯結中使用「隱藏」欄位時,最佳化工具處理
DISTINCT
的方式可能會與您未使用隱藏欄位時不同。在聯結中,隱藏欄位會被視為結果的一部分 (即使它們沒有顯示),而在一般查詢中,隱藏欄位不會參與DISTINCT
比較。以下是一個範例
SELECT DISTINCT mp3id FROM band_downloads WHERE userid = 9 ORDER BY id DESC;
和
SELECT DISTINCT band_downloads.mp3id FROM band_downloads,band_mp3 WHERE band_downloads.userid = 9 AND band_mp3.id = band_downloads.mp3id ORDER BY band_downloads.id DESC;
在第二種情況下,您可能會在結果集中取得兩個相同的列 (因為隱藏的
id
欄位中的值可能不同)。請注意,這只會發生在結果中沒有
ORDER BY
欄位的查詢。如果您在傳回空集合的查詢上執行
PROCEDURE
,在某些情況下,PROCEDURE
不會轉換欄位。建立類型為
MERGE
的資料表時,不會檢查基礎資料表的類型是否相容。如果您使用
ALTER TABLE
在MERGE
資料表中使用的資料表新增UNIQUE
索引,然後在MERGE
資料表新增一般索引,如果資料表中有舊的、非UNIQUE
索引,則資料表的索引鍵順序會不同。這是因為ALTER TABLE
會將UNIQUE
索引放在一般索引之前,以便盡早偵測到重複的索引鍵。