本節提供有關更有效使用 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
若要查看目前的按鍵繫結集,請暫時在 .editrc
的結尾放入一行,該行僅顯示 bind
。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 command line client - Unicode
的項目。此項目會使用已設定的屬性來呼叫 mysql 用戶端,以便使用 Unicode 通過主控台與 MySQL 伺服器進行通訊。
若要手動利用此支援,請在主控台中執行 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
子句。將
max_join_size
設定為 1,000,000 會導致多表格SELECT
陳述式,如果伺服器估計它必須檢查超過 1,000,000 個列組合時,產生錯誤。
若要指定與 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
選項,這會導致除了\C
和\d
以外的所有 mysql 指令在非互動模式下被停用(對於管道輸入到 mysql 或使用source
指令載入的輸入)。