MySQL常用經典語句
阿新 • • 發佈:2018-12-31
.重命名錶
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。
表示式(1,2)和ROW(1,2)有時被稱為行構造符。兩者是等同的,在其它的語境中,也是合法的。
例如,以下兩個語句在語義上是等同的(但是目前只有第二個語句可以被優化):
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管理程式已經處理了所有處於等待狀態的插入,並正在等待新插入。
多數狀態對應於非常快的操作。如果一個執行緒在這些狀態下停留了數秒,則可能是有問題,需要進行調查。
有一些其它的狀態,在前面的清單中沒有提及,但是其中有很多狀態對於查詢伺服器中的程式錯誤是有用的