1. 程式人生 > >MySQL常用經典語句

MySQL常用經典語句

.重命名錶
ALTER TABLE tbl1 RENAME tbl2;

.重命名錶
RENAME TABLE old_table TO backup_table;

重新命名多個表
RENAME TABLE old_table TO backup_table, new_table TO old_table;

.把表從一個庫移動到另一個庫
RENAME TABLE db1.tbl_name TO db2.tbl_name;

.刪去欄位
ALTER TABLE tbl DROP COLUMN filed1, DROP COLUMN field2;

刪除列c:
ALTER TABLE t2 DROP COLUMN c;

.把INTEGER型別的列的名稱從old_name變更到new_name
mysql> ALTER TABLE tbl CHANGE old_name new_name INTEGER;


.修改列的型別 (需要列出兩次列名)
ALTER TABLE tbl CHANGE filed1 filed1 BIGINT NOT NULL
; 或用modify(只需列出一次列名即可) ALTER TABLE tbl MODIFY field1 BIGINT NOT NULL; 把列a從INTERGER更改為TINYINT NOT NULL(名稱保持不變),並把列b從CHAR(10)更改為CHAR(20),同時把列b重新命名為列c: ALTER TABLE tbl MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20); .新增列 新增一個新的TIMESTAMP列,名稱為d: ALTER TABLE t2 ADD d TIMESTAMP; .在列d和列a中新增索引: ALTER TABLE t2 ADD INDEX (d), ADD INDEX (a); .建立有名索引 CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [USING index_type] ON tbl_name (index_col_name,...
) 列表(index_col_name,...)用於建立一個多列的組合索引 建立索引時,可以指定var或char型別的前幾個字元即可,索引使用列名稱的前10個字元。 CREATE INDEX part_of_name ON customer (name(10)); .建立索引時指定型別 部分儲存引擎允許在建立索引時指定索引型別。index_type指定語句的語法是USING type_name。 不同的儲存引擎所支援的type_name值已顯示在下表中。如果列有多個索引型別,當沒有指定index_type時,第一個型別是預設值。 儲存引擎 允許的索引型別 MyISAM BTREE InnoDB BTREE MEMORY/HEAP HASH, BTREE 示例: CREATE TABLE lookup (id INT) ENGINE = MEMORY; CREATE INDEX id_index USING BTREE ON lookup (id); TYPE type_name可以作為USING type_name的同義詞,用於指定索引型別。但是,USING是首選的格式。 另外,在索引規約語法中,位於索引型別前面的索引名稱不能使用TYPE。這是因為,與USING不同, TYPE不是保留詞,因此會被認為是一個索引名稱。 .新增一個新的AUTO_INCREMENT整數列,名稱為c: ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL
AUTO_INCREMENT, ADD PRIMARY KEY (c); .InnoDB取消外來鍵: ALTER TABLE tbl DROP FOREIGN KEY fk_symbol; .要把表預設的字符集和所有字元列(CHAR, VARCHAR, TEXT)改為新的字符集,應使用如下語句: ALTER TABLE tbl CONVERT TO CHARACTER SET new_charset_name; .修改列的字符集 ALTER TABLE tbl CHANGE field1 field1 TEXT CHARACTER SET utf8; .僅僅改變表的預設字符集 ALTER TABLE tbl DEFAULT CHARACTER SET new_charset_name; .如果InnoDB表在建立時,使用了.ibd檔案中的表空間,則這樣的檔案可以被刪除和匯入。使用此語句刪除.ibd檔案: ALTER TABLE tbl_name DISCARD TABLESPACE; .要把備份的.ibd檔案還原到表中,需把此檔案複製到資料庫目錄中,然後書寫此語句: ALTER TABLE tbl_name IMPORT TABLESPACE; .ALTER TABLE也可以用於對帶分割槽的表進行重新分割槽,功能包括新增、取消、合併和拆分各分割槽,還可以用於進行分割槽維護 假設您有一個按照以下方式建立的帶分割槽的表: CREATE TABLE t1 ( id INT, year_col INT ) PARTITION BY RANGE (year_col) ( PARTITION p0 VALUES LESS THAN (1991), PARTITION p1 VALUES LESS THAN (1995), PARTITION p2 VALUES LESS THAN (1999) ); 可以在表中增加一個新的分割槽p3,該分割槽用於儲存小於2002的值。新增方法如下: ALTER TABLE t1 ADD PARTITION p3 VALUES LESS THAN (2002); 註釋:您不能使用ALTER TABLE向一個沒有進行分割槽的表新增分割槽。 以採用如下方法取消名稱為p0和p1的分割槽: ALTER TABLE DROP PARTITION p0, p1; COALESCE PARTITION可以用於使用HASH或KEY進行分割槽的表,以便使用number來減少分割槽的數目。例如,假設您使用下列方法建立了表t2: CREATE TABLE t2 ( name VARCHAR (30), started DATE ) PARTITION BY HASH(YEAR(started)) PARTITIONS (6); 您可以使用以下命令,把t2使用的分割槽的數目由6個減少到4個: ALTER TABLE t2 COALESCE PARTITION 2; [注] ADD PARTITION和DROP PARTITION目前不支援IF [NOT] EXISTS 也不可能對一個分割槽或一個已分割槽的表進行重新命名。 要對一個分割槽進行重新命名,您必須取消分割槽,再重新建立; 如果您希望對一個已分割槽的表進行重新命名,您必須取消所有分割槽,然後對錶進行重新命名,再新增被取消的分割槽 .建立表 CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [( create_definition1, create_definition2, ... )] [table_options] [select_statement]; 或: CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(] LIKE old_tbl_name [)]; column_definition: col_name type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY] [COMMENT 'string'] [reference_definition] create_definition: column_definition | [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...) | KEY [index_name] [index_type] (index_col_name,...) | INDEX [index_name] [index_type] (index_col_name,...) | [CONSTRAINT [symbol]] UNIQUE [INDEX] [index_name] [index_type] (index_col_name,...) | [FULLTEXT|SPATIAL] [INDEX] [index_name] (index_col_name,...) | [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...) [reference_definition] | CHECK (expr) type: TINYINT[(length)] [UNSIGNED] [ZEROFILL] | SMALLINT[(length)] [UNSIGNED] [ZEROFILL] | MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL] | INT[(length)] [UNSIGNED] [ZEROFILL] | INTEGER[(length)] [UNSIGNED] [ZEROFILL] | BIGINT[(length)] [UNSIGNED] [ZEROFILL] | REAL[(length,decimals)] [UNSIGNED] [ZEROFILL] | DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL] | FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL] | DECIMAL(length,decimals) [UNSIGNED] [ZEROFILL] | NUMERIC(length,decimals) [UNSIGNED] [ZEROFILL] | DATE | TIME | TIMESTAMP | DATETIME | CHAR(length) [BINARY | ASCII | UNICODE] | VARCHAR(length) [BINARY] | TINYBLOB | BLOB | MEDIUMBLOB | LONGBLOB | TINYTEXT [BINARY] | TEXT [BINARY] | MEDIUMTEXT [BINARY] | LONGTEXT [BINARY] | ENUM(value1,value2,value3,...) | SET(value1,value2,value3,...) | spatial_type index_col_name: col_name [(length)] [ASC | DESC] reference_definition: REFERENCES tbl_name [(index_col_name,...)] [MATCH FULL | MATCH PARTIAL | MATCH SIMPLE] [ON DELETE reference_option] [ON UPDATE reference_option] reference_option: RESTRICT | CASCADE | SET NULL | NO ACTION table_options: table_option [table_option] ... table_option: {ENGINE|TYPE} = engine_name | AUTO_INCREMENT = value | AVG_ROW_LENGTH = value | [DEFAULT] CHARACTER SET charset_name [COLLATE collation_name] | CHECKSUM = {0 | 1} | COMMENT = 'string' | CONNECTION = 'connect_string' | MAX_ROWS = value | MIN_ROWS = value | PACK_KEYS = {0 | 1 | DEFAULT} | PASSWORD = 'string' | DELAY_KEY_WRITE = {0 | 1} | ROW_FORMAT = {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT} | UNION = (tbl_name[,tbl_name]...) | INSERT_METHOD = { NO | FIRST | LAST } | DATA DIRECTORY = 'absolute path to directory' | INDEX DIRECTORY = 'absolute path to directory' partition_options: PARTITION BY [LINEAR] HASH(expr) | [LINEAR] KEY(column_list) | RANGE(expr) | LIST(column_list) [PARTITIONS num] [ SUBPARTITION BY [LINEAR] HASH(expr) | [LINEAR] KEY(column_list) [SUBPARTITIONS(num)] ] [(partition_definition), [(partition_definition)], ...] partition_definition: PARTITION partition_name [VALUES { LESS THAN (expr) | MAXVALUE | IN (value_list) }] [[STORAGE] ENGINE [=] engine-name] [COMMENT [=] 'comment_text' ] [DATA DIRECTORY [=] 'data_dir'] [INDEX DIRECTORY [=] 'index_dir'] [MAX_ROWS [=] max_number_of_rows] [MIN_ROWS [=] min_number_of_rows] [TABLESPACE [=] (tablespace_name)] [NODEGROUP [=] node_group_id] [(subpartition_definition), [(subpartition_definition)], ...] subpartition_definition: SUBPARTITION logical_name [[STORAGE] ENGINE [=] engine-name] [COMMENT [=] 'comment_text' ] [DATA DIRECTORY [=] 'data_dir'] [INDEX DIRECTORY [=] 'index_dir'] [MAX_ROWS [=] max_number_of_rows] [MIN_ROWS [=] min_number_of_rows] [TABLESPACE [=] (tablespace_name)] [NODEGROUP [=] node_group_id] select_statement: [IGNORE | REPLACE] [AS] SELECT ... (Some legal select statement) CREATE TABLE用於建立帶給定名稱的表。您必須擁有表CREATE許可權。 .字元列的定義可以包括一個CHARACTER SET屬性,用來指定字符集,也可以指定列的整序。CHARSET是CHARACTER SET的同義詞。 CREATE TABLE t ( c CHAR(20) CHARACTER SET utf8 COLLATE utf8_bin ); 對於一個給定的表,您可以使用SHOW CREATE TABLE語句來檢視那些列有明確的DEFAULT子句。 COMMENT : 對於列的評註。評註通過SHOW CREATE TABLE和SHOW FULL COLUMNS語句顯示。 SERIAL : 屬性SERIAL可以用作BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE的別名。 KEY : 通常是INDEX同義詞。如果關鍵字屬性PRIMARY KEY在列定義中已給定,則PRIMARY KEY也可以只指定為KEY。 這麼做的目的是與其它資料庫系統相容。 UNIQUE : 在UNIQUE索引中,所有的值必須互不相同。如果您在新增新行時使用的關鍵字與原有行的關鍵字相同, 則會出現錯誤。例外情況是,如果索引中的一個列允許包含NULL值,則此列可以包含多個NULL值。 此例外情況不適用於BDB表。在BDB中,帶索引的列只允許一個單一NULL。 PRIMARY KEY : 是一個唯一KEY,此時,所有的關鍵字列必須定義為NOT NULL。如果這些列沒有被明確地定義為NOT NULL, MySQL應隱含地定義這些列。一個表只有一個PRIMARY KEY。如果您沒有PRIMARY KEY並且一個應用程式要求 在表中使用PRIMARY KEY,則MySQL返回第一個UNIQUE索引,此索引沒有作為PRIMARY KEY的NULL列。 在已建立的表中,PRIMARY KEY的位置最靠前,然後是所有的UNIQUE索引,然後是非唯一索引。這可以幫助MySQL優化 程式選擇優先使用哪個索引,並且更快速的檢測出重複的UNIQUE關鍵字。 PRIMARY KEY可以是一個多列索引。但是,在列規約中使用PRIMARY KEY關鍵字屬性無法建立多列索引。這麼做只能把一個 列標記為主列。您必須使用一個單獨的PRIMARY KEY(index_col_name, ...)子句。 如果PRIMARY KEY或UNIQUE索引只包括一個列,並且此列為整數型別,則您也可以在SELECT語句中把此列作為_rowid引用。 在MySQL中,PRIMARY KEY的名稱為PRIMARY。對於其它索引,如果您沒有賦予名稱,則索引被賦予的名稱與第一個已編入 索引的列的名稱相同,並自選新增字尾(_2, _3,...),使名稱為唯一名稱。您可以使用SHOW INDEX FROM tbl_name來查 看錶的索引名稱。請參見13.5.4.11節,“SHOW INDEX語法”。 部分儲存引擎允許您在建立索引時指定索引型別。index_type指示語句的語法是USING type_name。 .部分儲存引擎允許您在建立索引時指定索引型別。index_type指示語句的語法是USING type_name。 CREATE TABLE lookup ( id INT, INDEX USING BTREE (id) ) ENGINE = MEMORY; .重新設定AUTO_INCREMENT值 ALTER TABLE tbl_name AUTO_INCREMENT = n; .COMMENT 表的註釋,最長60個字元。 .MySQL會對SELECT中的所有項建立新列。舉例說明: CREATE TABLE test ( a INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (a), KEY(b) ) TYPE=MyISAM SELECT b,c FROM test2; 本語句用於建立含三個列(a, b, c)的MyISAM表。注意,用SELECT語句建立的列附在表的右側,而不是覆蓋在表 mysql> CREATE TABLE bar (m INT) SELECT n FROM foo; Query OK, 1 row affected (0.02 sec) mysql> SELECT * FROM bar; +------+---+ | m | n | +------+---+ | NULL | 1 | +------+---+ 1 row in set (0.00 sec) .刪除資料庫 DROP {DATABASE | SCHEMA} [IF EXISTS] db_name; .刪除索引 DROP INDEX index_name ON tbl_name; .刪除表 DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name] ... [RESTRICT | CASCADE]; 例:刪除一個表 DROP TABLE IF EXISTS my_tbl1; 刪除多個表 DROP TABLE IF EXISTS my_tbl1, my_tbl2; .可以同時刪除許多個表中的行,並使用其它的表進行搜尋: DELETE t1, t2 FROM t1, t2, t3 WHERE t1.id=t2.id AND t2.id=t3.id; 或: DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.id=t2.id AND t2.id=t3.id; .向表中插入資料語法 INSERT INTO tbl_name (f1, f2, f3) VALUES(val1, val2, val3); .指定了ON DUPLICATE KEY UPDATE,插入行後會導致在一個UNIQUE索引或PRIMARY KEY中出現重複值,則執行舊行UPDATE。 例如,如果列a被定義為UNIQUE,並且包含值1,則以下兩個語句具有相同的效果: INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1; INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6) ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b); .Load data匯入資料 LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table; .如果需要LOAD DATA來從一個管道中讀取,可以使用以下方法(此處我們把/目錄清單載入一個表格): mkfifo /mysql/db/x/x chmod 666 /mysql/db/x/x find / -ls > /mysql/db/x/x mysql -e "LOAD DATA INFILE 'x' INTO TABLE x" x 有些輸入記錄把原有的記錄複製到唯一關鍵字值上。REPLACE和IGNORE關鍵字用於控制這些輸入記錄的操作。 .如果所有讀入的行都含有一個共用字首,則您可以使用'prefix_string'來跳過字首(和字首前的字元)。 如果某行不包括字首,則整個行被跳過。註釋:prefix_string會出現在一行的中間。 LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test LINES STARTING BY "xxx"; .給定別名時,AS關鍵詞是自選的 SELECT CONCAT(last_name,', ',first_name) AS full_name FROM mytable ORDER BY full_name; 或 SELECT CONCAT(last_name,', ',first_name) full_name FROM mytable ORDER BY full_name; .連線表 (您不應對ON部分有任何條件。ON部分用於限定在結果集合中您想要哪些行。但是,您應在WHERE子句中指定這些條件) SELECT * FROM t1 LEFT JOIN (t2, t3, t4) ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c); 相當於 SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4) ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c); .子查詢 SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2); .多步子查詢 DELETE FROM t1 WHERE s11 > ANY( SELECT COUNT(*) /* no hint */ FROM t2 WHERE NOT EXISTS( SELECT * FROM t3 WHERE ROW(5*t2.s1,77)= ( SELECT 50,11*s1 FROM t4 UNION SELECT 50,77 FROM( SELECT * FROM t5) AS t5 ) ) ); SELECT s1 FROM t1 WHERE s1 > ANY (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 IN (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 NOT IN (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 <> ANY (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 <> SOME (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 > ALL (SELECT s1 FROM t2); .行子查詢 行子查詢是一個能返回一個單一行的子查詢變數,因此可以返回一個以上的列值。以下是兩個例子: SELECT * FROM t1 WHERE (1,2) = (SELECT column1, column2 FROM t2); SELECT * FROM t1 WHERE ROW(1,2) = (SELECT column1, column2 FROM t2); 如果在表t2的一個行中,column1=1並且column2=2,則查詢結果均為TRUE。 表示式(12)和ROW(12)有時被稱為行構造符。兩者是等同的,在其它的語境中,也是合法的。 例如,以下兩個語句在語義上是等同的(但是目前只有第二個語句可以被優化): SELECT * FROM t1 WHERE (column1,column2) = (1,1); SELECT * FROM t1 WHERE column1 = 1 AND column2 = 1; 行構造符通常用於與對能返回兩個或兩個以上列的子查詢進行比較。 例如,以下查詢可以答覆請求,“在表t1中查詢同時也存在於表t2中的所有的行”: SELECT column1,column2,column3 FROM t1 WHERE (column1,column2,column3) IN (SELECT column1,column2,column3 FROM t2); .如果一個子查詢返回任何的行,則EXISTS subquery為FALSE。例如: SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2); 哪些種類的商店出現在一個或多個城市裡 SELECT DISTINCT store_type FROM stores WHERE EXISTS ( SELECT * FROM cities_stores WHERE cities_stores.store_type = stores.store_type); 哪些種類的商店沒有出現在任何城市裡 SELECT DISTINCT store_type FROM stores WHERE NOT EXISTS ( SELECT * FROM cities_stores WHERE cities_stores.store_type = stores.store_type); 哪些種類的商店出現在所有城市裡 SELECT DISTINCT store_type FROM stores s1 WHERE NOT EXISTS ( SELECT * FROM cities WHERE NOT EXISTS ( SELECT * FROM cities_stores WHERE cities_stores.city = cities.city AND cities_stores.store_type = stores.store_type ) ); .相關聯的子查詢是一個包含對錶的引用的子查詢。該表也顯示在外部查詢中。例如: SELECT * FROM t1 WHERE column1 = ANY(SELECT column1 FROM t2 WHERE t2.column2 = t1.column2); .完全清空一個表 TRUNCATE TABLE my_tbl; 與DELETE語句不同的是: 對於InnoDB表,如果有需要引用表的外來鍵限制,則TRUNCATE TABLE被對映到DELETE上; 否則使用快速刪減(取消和重新建立表)。使用TRUNCATE TABLE重新設定AUTO_INCREMENT計數器,設定時不考慮是否有外來鍵限制。 .事務 START TRANSACTION; SELECT @A:=SUM(salary) FROM table1 WHERE type=1; UPDATE table2 SET [email protected] WHERE type=1; COMMIT; .LOCK TABLES和UNLOCK TABLES語法 LOCK TABLES tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE} [, tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}] ... UNLOCK TABLES mysql> LOCK TABLE t WRITE, t AS t1 WRITE; mysql> INSERT INTO t SELECT * FROM t; ERROR 1100: Table 't' was not locked with LOCK TABLES mysql> INSERT INTO t SELECT * FROM t AS t1; 如果您的查詢使用一個別名引用一個表,那麼您必須使用同樣的別名鎖定該表。如果沒有指定別名,則不會鎖定該表。 mysql> LOCK TABLE t READ; mysql> SELECT * FROM t AS myalias; ERROR 1100: Table 'myalias' was not locked with LOCK TABLES 相反的,如果您使用一個別名鎖定一個表,您必須使用該別名在您的查詢中引用該表。 mysql> LOCK TABLE t AS myalias READ; mysql> SELECT * FROM t; ERROR 1100: Table 't' was not locked with LOCK TABLES mysql> SELECT * FROM t AS myalias 果您正在使用MySQL中的一個不支援事務的儲存引擎,則如果您想要確定在SELECT和UPDATE之間沒有其它執行緒,您必須使用LOCK TABLES。本處所示的例子要求LOCK TABLES,以便安全地執行: mysql> LOCK TABLES trans READ, customer WRITE; mysql> SELECT SUM(value) FROM trans WHERE customer_id=some_id; mysql> UPDATE customer -> SET total_value=sum_from_previous_statement -> WHERE customer_id=some_id; mysql> UNLOCK TABLES; 如果沒有LOCK TABLES,有可能另一個執行緒會在執行SELECT和UPDATE語句之間在trans表中插入一個新行。 .分析表 ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ... .CHECK TABLE語法 CHECK TABLE tbl_name [, tbl_name] ... [option] ... option = {QUICK | FAST | MEDIUM | EXTENDED | CHANGED} .OPTIMIZE TABLE語法 OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ... 如果您已經刪除了表的一大部分,或者如果您已經對含有可變長度行的表(含有VARCHAR, BLOB或TEXT列的表)進行了很多更改,則應使用OPTIMIZE TABLE。被刪除的記錄被保持在連結清單中,後續的INSERT操作會重新使用舊的記錄位置。您可以使用OPTIMIZE TABLE來重新利用未使用的空間,並整理資料檔案的碎片。 在多數的設定中,您根本不需要執行OPTIMIZE TABLE。即使您對可變長度的行進行了大量的更新,您也不需要經常執行,每週一次或每月一次即可,只對特定的表執行。 OPTIMIZE TABLE只對MyISAM, BDB和InnoDB表起作用。 對於MyISAM表,OPTIMIZE TABLE按如下方式操作: 1.如果表已經刪除或分解了行,則修復表。 2.如果未對索引頁進行分類,則進行分類。 3.如果表的統計資料沒有更新(並且通過對索引進行分類不能實現修復),則進行更新。 對於BDB表,OPTIMIZE TABLE目前被對映到ANALYZE TABLE上。對於InnoDB表,OPTIMIZE TABLE被對映到ALTER TABLE上,這會重建表。重建操作能更新索引統計資料並釋放成簇索引中的未使用的空間。 使用—skip-new或—safe-mode選項可以啟動mysqld。通過啟動mysqld,您可以使OPTIMIZE TABLE對其它表型別起作用。 注意,在OPTIMIZE TABLE執行過程中,MySQL會鎖定表。 OPTIMIZE TABLE語句被寫入到二進位制日誌中,除非使用了自選的NO_WRITE_TO_BINLOG關鍵詞(或其別名LOCAL)。已經這麼做了,因此,用於MySQL伺服器的OPTIMIZE TABLE命令的作用相當於一個複製主伺服器,在預設情況下,這些命令將被複制到複製從屬伺服器中。 .REPAIR TABLE語法 REPAIR [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ... [QUICK] [EXTENDED] [USE_FRM] .RESTORE TABLE語法 RESTORE TABLE tbl_name [, tbl_name] ... FROM '/path/to/backup/directory' 用於恢復來自用BACKUP TABLE製作的備份的表。原有的表不會被覆蓋;如果您試圖覆蓋一個原有的表,會發生錯誤。 .SHOW系列 SHOW [FULL] COLUMNS FROM tbl_name [FROM db_name] [LIKE 'pattern'] SHOW CREATE DATABASE db_name SHOW CREATE TABLE tbl_name SHOW DATABASES [LIKE 'pattern'] SHOW ENGINE engine_name {LOGS | STATUS } SHOW [STORAGE] ENGINES SHOW ERRORS [LIMIT [offset,] row_count] SHOW GRANTS [FOR user] SHOW INDEX FROM tbl_name [FROM db_name] SHOW INNODB STATUS SHOW [BDB] LOGS SHOW PRIVILEGES SHOW [FULL] PROCESSLIST SHOW [GLOBAL | SESSION] STATUS [LIKE 'pattern'] SHOW TABLE STATUS [FROM db_name] [LIKE 'pattern'] SHOW [OPEN] TABLES [FROM db_name] [LIKE 'pattern'] SHOW TRIGGERS SHOW [GLOBAL | SESSION] VARIABLES [LIKE 'pattern'] SHOW WARNINGS [LIMIT [offset,] row_count] SHOW BINLOG EVENTS SHOW MASTER LOGS SHOW MASTER STATUS SHOW SLAVE HOSTS SHOW SLAVE STATUS SHOW PROCESSLIST語法 SHOW [FULL] PROCESSLIST SHOW PROCESSLIST顯示哪些執行緒正在執行。您也可以使用mysqladmin processlist語句得到此資訊。如果您有SUPER許可權,您可以看到所有執行緒。否則,您只能看到您自己的執行緒(也就是,與您正在使用的MySQL賬戶相關的執行緒)。請參見13.5.5.3節,“KILL語法”。如果您不使用FULL關鍵詞,則只顯示每個查詢的前100個字元。 本語句報告TCP/IP連線的主機名稱(採用host_name:client_port格式),以方便地判定哪個客戶端正在做什麼。 如果您得到“too many connections”錯誤資訊,並且想要了解正在發生的情況,本語句是非常有用的。MySQL保留一個額外的連線,讓擁有SUPER許可權的 賬戶使用,以確保管理員能夠隨時連線和檢查系統(假設您沒有把此許可權給予所有的使用者)。 在來自SHOW PROCESSLIST的輸出中常見的一些狀態: Checking table 執行緒正在執行(自動)表格檢查。 Closing tables 意味著執行緒正在重新整理更改後的表資料,並正在關閉使用過的表。這應該是一個快速的操作。如果不快,則您應該驗證您的磁碟沒有充滿,並且磁碟沒有被超負荷使用。 Connect Out 連線到主伺服器上的從屬伺服器。 Copying to tmp table on disk 臨時結果集合大於tmp_table_size。執行緒把臨時表從儲存器內部格式改變為磁碟模式,以節約儲存器。 Creating tmp table 執行緒正在建立一個臨時表,以保持部分結果。 deleting from main table 伺服器正在執行多表刪除的第一部分,只從第一個表中刪除。 deleting from reference tables 伺服器正在執行多表刪除的第二部分,從其它表中刪除匹配的行。 Flushing tables 執行緒正在執行FLUSH TABLES,並正在等待所有執行緒,以關閉表。 FULLTEXT initialization 伺服器正在準備執行一個自然語言全文字搜尋。 Killed 有人已經向執行緒傳送了一個KILL命令。在下一次檢查終止標記時,應放棄。該標記在MySQL的每個大迴圈中都檢查,但是在有些情況下,執行緒終止只需要較短的時間。如果該執行緒被其它執行緒鎖定,則只要其它執行緒接觸鎖定,終止操作就會生效。 Locked 該查詢被其它查詢鎖定。 Sending data 執行緒正在為SELECT語句處理行,同時正在向客戶端傳送資料。 Sorting for group 執行緒正在進行分類,以滿足GROUP BY要求。 Sorting for order 執行緒正在進行分類,以滿足ORDER BY要求。 Opening tables 執行緒正在試圖開啟一個表。這應該是非常快的過程,除非開啟操作受到阻止。例如,一個ALTER TABLE或一個LOCK TABLE語句可以阻止開啟一個表,直到語句完成為止。 Removing duplicates 查詢正在使用SELECT DISTINCT。使用時,在早期階段,MySQL不能優化不同的操作。因此,MySQL要求一個額外的階段,以便在把結果傳送給客戶端之前取消所有的複製行。 Reopen table 執行緒得到一個表鎖定,但是在得到鎖定後被通知帶下方的表結構已更改了。它已經釋放了鎖定,關閉了表,並試圖重新開啟它。 Repair by sorting 修復程式碼正在使用一個分類來建立索引。 Repair with keycache 修復程式碼正在通過關鍵快取一個接一個地使用建立關鍵字。這比通過分類修復要慢很多。 Searching rows for update 執行緒正在進行第一階段,以在更新之前,查詢所有匹配的行。如果UPDATE正在更改用於查詢相關行的索引,則必須這麼做。 Sleeping 執行緒正在等待客戶端,以向它傳送一個新語句。 System lock 執行緒正在等待得到一個用於表的外部系統鎖定。如果您沒有正在使用多個正在訪問同一個表的mysqld伺服器,則您可以使用--skip-external-locking選項禁用系統鎖定。 Upgrading lock INSERT DELAYED管理程式正在試圖得到一個表鎖定,以插入行。 Updating 執行緒正在搜尋行,並正在更新這些行。 User Lock 執行緒正在等待GET_LOCK()。 Waiting for tables 執行緒得到一個通知,表的底層結構已經改變,需要重新開啟表以得到新的結構。但是,為了能重新開啟表,必須等待,直到所有其它的執行緒已經關閉了正在被質詢的表。 如果其它執行緒已經對正在被質詢的表使用了FLUSH TABLES或以下語句之一:FLUSH TABLES tbl_name, ALTER TABLE, RENAME TABLE, REPAIR TABLE, ANALYZE TABLE或OPTIMIZE TABLE;則會出現通知。 waiting for handler insert INSERT DELAYED管理程式已經處理了所有處於等待狀態的插入,並正在等待新插入。 多數狀態對應於非常快的操作。如果一個執行緒在這些狀態下停留了數秒,則可能是有問題,需要進行調查。 有一些其它的狀態,在前面的清單中沒有提及,但是其中有很多狀態對於查詢伺服器中的程式錯誤是有用的