本節提供有關更有效使用 mysql 的技術,以及關於 mysql 操作行為的資訊。
輸入行編輯
mysql 支援輸入行編輯,這可讓您就地修改目前的輸入行或回溯先前的輸入行。例如,左箭頭 和 右箭頭 鍵可在目前的輸入行中水平移動,而 上箭頭 和 下箭頭 鍵可在先前輸入的行集合中上下移動。退格鍵 會刪除游標前的字元,而輸入新字元會將它們輸入到游標位置。若要輸入該行,請按下 Enter。
在 Windows 上,編輯按鍵順序與主控台視窗中支援的命令編輯相同。在 Unix 上,按鍵順序取決於用於建置 mysql 的輸入程式庫 (例如,libedit
或 readline
程式庫)。
線上提供 libedit
和 readline
程式庫的文件。若要變更給定輸入程式庫允許的按鍵順序集合,請在程式庫啟動檔案中定義按鍵繫結。這是您主目錄中的檔案:.editrc
用於 libedit
,而 .inputrc
用於 readline
。
例如,在 libedit
中,Control+W 會刪除目前游標位置之前的所有內容,而 Control+U 會刪除整行。在 readline
中,Control+W 會刪除游標前的單字,而 Control+U 會刪除目前游標位置之前的所有內容。如果 mysql 是使用 libedit
建置的,則偏好這兩個按鍵的 readline
行為的使用者可以將下列行放在 .editrc
檔案中 (如果需要,請建立該檔案)
bind "^W" ed-delete-prev-word
bind "^U" vi-kill-line-prev
若要查看目前的按鍵繫結集合,請暫時將僅顯示 bind
的行放在 .editrc
的結尾。mysql 會在啟動時顯示繫結。
停用互動式歷史記錄
上箭頭 鍵可讓您從目前和先前的連線回溯輸入行。在共用主控台的情況下,此行為可能不適合。mysql 支援部分或完全停用互動式歷史記錄,具體取決於主機平台。
在 Windows 上,歷史記錄會儲存在記憶體中。Alt+F7 會刪除儲存在記憶體中目前歷史記錄緩衝區的所有輸入行。它也會刪除使用 F7 顯示並使用 F9 (依編號) 回溯的輸入行前面的連續數字清單。按下 Alt+F7 後輸入的新輸入行會重新填入目前的歷史記錄緩衝區。如果使用 --syslog
選項啟動 mysql,則清除緩衝區不會防止記錄到 Windows 事件檢視器。關閉主控台視窗也會清除目前的歷史記錄緩衝區。
若要在 Unix 上停用互動式歷史記錄,請先刪除 .mysql_history
檔案(如果存在),否則會回溯先前的輸入項目。然後使用 --histignore="*"
選項啟動 mysql,以忽略所有新的輸入行。若要重新啟用回溯(以及記錄)行為,請在不使用該選項的情況下重新啟動 mysql。
如果您阻止 .mysql_history
檔案建立(請參閱控制歷史檔案),並使用 --histignore="*"
啟動 mysql 用戶端,則會完全停用互動式歷史記錄回溯功能。或者,如果您省略 --histignore
選項,您可以回溯目前工作階段期間輸入的行。
Windows 上的 Unicode 支援
Windows 提供基於 UTF-16LE 的 API,用於從主控台讀取和寫入;適用於 Windows 的 mysql 用戶端能夠使用這些 API。Windows 安裝程式會在 MySQL 選單中建立一個名為 MySQL 命令列用戶端 - Unicode
的項目。此項目會使用設定好的屬性來呼叫 mysql 用戶端,以便透過主控台與 MySQL 伺服器使用 Unicode 進行通訊。
若要手動利用此支援,請在主控台內執行 mysql,該主控台使用相容的 Unicode 字型,並將預設字元集設定為支援與伺服器通訊的 Unicode 字元集。
開啟主控台視窗。
前往主控台視窗屬性,選取字型索引標籤,然後選擇 Lucida Console 或其他相容的 Unicode 字型。這是必要的,因為主控台視窗預設啟動時使用 DOS 點陣字型,這對於 Unicode 來說是不夠的。
使用
--default-character-set=utf8mb4
(或utf8mb3
)選項執行 mysql.exe。此選項是必要的,因為utf16le
是無法用作用戶端字元集的字元集之一。請參閱不允許的用戶端字元集。
進行這些變更後,mysql 會使用 Windows API 透過 UTF-16LE 與主控台通訊,並使用 UTF-8 與伺服器通訊。(前面提到的選單項目會如前所述設定字型和字元集。)
若要避免每次執行 mysql 時都執行這些步驟,您可以建立一個捷徑來呼叫 mysql.exe。捷徑應將主控台字型設定為 Lucida Console 或其他相容的 Unicode 字型,並將 --default-character-set=utf8mb4
(或 utf8mb3
)選項傳遞至 mysql.exe。
或者,建立一個只設定主控台字型的捷徑,並在 my.ini
檔案的 [mysql]
群組中設定字元集。
[mysql]
default-character-set=utf8mb4 # or utf8mb3
垂直顯示查詢結果
某些查詢結果以垂直方式顯示時,會比以通常的水平表格格式更具可讀性。可以透過使用 \G 而不是分號來結束查詢,以垂直方式顯示查詢。例如,包含換行符號的較長文字值,通常更容易以垂直輸出方式閱讀。
mysql> SELECT * FROM mails WHERE LENGTH(txt) < 300 LIMIT 300,1\G
*************************** 1. row ***************************
msg_nro: 3068
date: 2000-03-01 23:29:50
time_zone: +0200
mail_from: Jones
reply: jones@example.com
mail_to: "John Smith" <smith@example.com>
sbj: UTF-8
txt: >>>>> "John" == John Smith writes:
John> Hi. I think this is a good idea. Is anyone familiar
John> with UTF-8 or Unicode? Otherwise, I'll put this on my
John> TODO list and see what happens.
Yes, please do that.
Regards,
Jones
file: inbox-jani-1
hash: 190402944
1 row in set (0.09 sec)
使用安全更新模式 (--safe-updates)
對於初學者來說,有用的啟動選項是 --safe-updates
(或 --i-am-a-dummy
,效果相同)。當您可能發出 UPDATE
或 DELETE
陳述式,但忘記指示要修改哪些列的 WHERE
子句時,安全更新模式會很有幫助。通常,此類陳述式會更新或刪除表格中的所有列。使用 --safe-updates
,您只能透過指定識別列的金鑰值、LIMIT
子句,或兩者來修改列。這有助於防止意外發生。安全更新模式還會限制產生(或估計會產生)非常大結果集的 SELECT
陳述式。
--safe-updates
選項會導致 mysql 在連線至 MySQL 伺服器時執行以下陳述式,以設定 sql_safe_updates
、sql_select_limit
和 max_join_size
系統變數的工作階段值。
SET sql_safe_updates=1, sql_select_limit=1000, max_join_size=1000000;
SET
陳述式會以下列方式影響陳述式處理:
啟用
sql_safe_updates
會導致UPDATE
和DELETE
陳述式在WHERE
子句中未指定金鑰約束,或未提供LIMIT
子句,或兩者皆無時,產生錯誤。例如:UPDATE tbl_name SET not_key_column=val WHERE key_column=val; UPDATE tbl_name SET not_key_column=val LIMIT 1;
將
sql_select_limit
設定為 1,000 會導致伺服器將所有SELECT
結果集限制為 1,000 列,除非該陳述式包含LIMIT
子句。如果伺服器估計必須檢查超過 1,000,000 列的組合,則將
max_join_size
設定為 1,000,000 會導致多表格SELECT
陳述式產生錯誤。
若要指定與 1,000 和 1,000,000 不同的結果集限制,您可以在呼叫 mysql 時,使用 --select-limit
和 --max-join-size
選項來覆寫預設值。
mysql --safe-updates --select-limit=500 --max-join-size=10000
即使在 WHERE
子句中指定了金鑰,如果最佳化工具決定不使用金鑰欄上的索引,UPDATE
和 DELETE
陳述式仍可能會在安全更新模式下產生錯誤。
如果記憶體使用量超過
range_optimizer_max_mem_size
系統變數允許的範圍,則無法使用索引上的範圍存取。然後,最佳化工具會回復到表格掃描。請參閱限制範圍最佳化的記憶體使用量。如果金鑰比較需要類型轉換,則可能不會使用索引(請參閱第 10.3.1 節,〈MySQL 如何使用索引〉)。假設索引字串欄
c1
使用WHERE c1 = 2222
與數值進行比較。對於此類比較,字串值會轉換為數字,並以數值方式比較運算元(請參閱第 14.3 節,〈表達式評估中的類型轉換〉),防止使用索引。如果啟用安全更新模式,則會發生錯誤。
這些行為包含在安全更新模式中:
使用
UPDATE
和DELETE
陳述式的EXPLAIN
不會產生安全更新錯誤。這可讓您使用EXPLAIN
加上SHOW WARNINGS
來查看為何未使用索引,這在range_optimizer_max_mem_size
違規或發生類型轉換,且最佳化工具即使在WHERE
子句中指定了金鑰欄,也不會使用索引等情況下,會很有幫助。發生安全更新錯誤時,錯誤訊息會包含產生的第一個診斷,以提供有關失敗原因的資訊。例如,訊息可能指出已超過
range_optimizer_max_mem_size
值或發生類型轉換,這兩者都可能會排除索引的使用。對於多表格刪除和更新,只有在任何目標表格使用表格掃描時,才會在啟用安全更新時產生錯誤。
停用 mysql 自動重新連線
如果在傳送語句時,mysql 客戶端與伺服器的連線中斷,它會立即自動嘗試重新連線到伺服器,並再次傳送該語句。然而,即使 mysql 成功重新連線,您的第一個連線也已結束,並且您之前的所有會話物件和設定都會遺失:臨時表、自動提交模式、使用者定義變數和會話變數。此外,任何目前的交易都會回滾。這種行為對您來說可能是危險的,如下面的範例所示,伺服器在您不知情的情況下於第一條和第二條語句之間關閉並重新啟動
mysql> SET @a=1;
Query OK, 0 rows affected (0.05 sec)
mysql> INSERT INTO t VALUES(@a);
ERROR 2006: MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 1
Current database: test
Query OK, 1 row affected (1.30 sec)
mysql> SELECT * FROM t;
+------+
| a |
+------+
| NULL |
+------+
1 row in set (0.05 sec)
@a
使用者變數已隨著連線遺失,並且在重新連線後未定義。如果希望在連線遺失時 mysql 以錯誤終止,您可以使用 --skip-reconnect
選項啟動 mysql 客戶端。
有關自動重新連線及其在重新連線發生時對狀態資訊的影響的更多資訊,請參閱 自動重新連線控制。
mysql 客戶端解析器與伺服器解析器
mysql 客戶端在客戶端使用解析器,該解析器並非伺服器端 mysqld 伺服器使用的完整解析器的副本。這可能會導致對某些結構的處理方式有所不同。範例:
如果啟用了
ANSI_QUOTES
SQL 模式,則伺服器解析器會將由"
字元分隔的字串視為識別符,而不是純字串。mysql 客戶端解析器不考慮
ANSI_QUOTES
SQL 模式。無論是否啟用ANSI_QUOTES
,它都以相同的方式處理由"
、'
和`
字元分隔的字串。在
/*! ... */
和/*+ ... */
註解中,mysql 客戶端解析器會解譯簡短形式的 mysql 指令。伺服器解析器不會解譯它們,因為這些指令在伺服器端沒有意義。如果希望 mysql 不解譯註解中的簡短形式指令,一種部分解決方法是使用
--binary-mode
選項,這會導致所有 mysql 指令(除了非互動模式下的\C
和\d
)被停用(用於輸入管道到 mysql 或使用source
指令載入)。