對MySQL DELETE語法的詳細解析

如下的文章主要描述的是MySQL DELETE語法的詳細解析,首先咱們是從單表語法與多表語法的示例開始的,假如你對MySQL DELETE語法的相關內容十分感興趣的話,你就能夠瀏覽如下的文章對其有個更好的瞭解。

單表語法:

DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name  
[WHERE where_definition]  
[ORDER BY ...]  
[LIMIT row_count] 

多表語法:

DELETE [LOW_PRIORITY] [QUICK] [IGNORE]  
tbl_name[.*] [, tbl_name[.*] ...]  
FROM table_references  
[WHERE where_definition] 
或:

DELETE [LOW_PRIORITY] [QUICK] [IGNORE]  
FROM tbl_name[.*] [, tbl_name[.*] ...]  
USING table_references  
[WHERE where_definition] 
tbl_name中有些行知足由where_definition給定的條件。MySQL DELETE用於刪除這些行,並返回被刪除的記錄的數目。

若是您編寫的DELETE語句中沒有WHERE子句,則全部的行都被刪除。當您不想知道被刪除的行的數目時,有一個更快的方法,即便用TRUNCATE TABLE。

若是您刪除的行中包括用於AUTO_INCREMENT列的最大值,則該值被從新用於BDB表,可是不會被用於MyISAM表或InnoDB表。若是您在AUTOCOMMIT模式下使用DELETE FROM tbl_name(不含WHERE子句)刪除表中的全部行,則對於全部的表類型(除InnoDB和MyISAM外),序列從新編排。對於InnoDB表,此項操做有一些例外。

對於MyISAM和BDB表,您能夠把AUTO_INCREMENT次級列指定到一個多列關鍵字中。在這種狀況下,從序列的頂端被刪除的值被再次使用,甚至對於MyISAM表也如此。DELETE語句支持如下修飾符:

若是您指定LOW_PRIORITY,則DELETE的執行被延遲,直到沒有其它客戶端讀取本表時再執行。

對於MyISAM表,若是您使用QUICK關鍵詞,則在刪除過程當中,存儲引擎不會合並索引端結點,這樣能夠加快部分種類的刪除操做的速度。

在刪除行的過程當中,IGNORE關鍵詞會使MySQL忽略全部的錯誤。(在分析階段遇到的錯誤會以常規方式處理。)因爲使用本選項而被忽略的錯誤會做爲警告返回。

刪除操做的速度會受到一些因素的影響,這些因素在7.2.18節,「MySQL DELETE語句的速度」中進行了討論。

在MyISAM表中,被刪除的記錄被保留在一個帶連接的清單中,後續的INSERT操做會從新使用舊的記錄位置。要從新使用未使用的空間並減少文件的尺寸,則使用OPTIMIZE TABLE語句或myisamchk應用程序從新編排表。OPTIMIZE TABLE更簡便,可是myisamchk速度更快。請參見13.5.2.5節,「OPTIMIZE TABLE語法」和第7章:優化。

QUICK修飾符會影響到在刪除操做中索引端結點是否合併。當用於被刪除的行的索引值被來自後插入的行的相近的索引值代替時,DELETE QUICK最爲適用。在此狀況下,被刪除的值留下來的空穴被從新使用。

未充滿的索引塊跨越某一個範圍的索引值,會再次發生新的插入。當被刪除的值致使出現未充滿的索引塊時,DELETE QUICK沒有做用。在此狀況下,使用QUICK會致使未利用的索引中出現廢棄空間。下面是此種狀況的舉例說明:

1. 建立一個表,表中包含已編索引的AUTO_INCREMENT列。

2. 在表中插入不少記錄。每次插入會產生一個索引值,此索引值被添加到索引的高端處。

3. 使用DELETE QUICK從列的低端處刪除一組記錄。

在此狀況下,與被刪除的索引值相關的索引塊變成未充滿的狀態,可是,因爲使用了QUICK,這些索引塊不會與其它索引塊合併。當插入新值時,這些索引塊仍爲未充滿的狀態,緣由是新記錄不含有在被刪除的範圍內的索引值。另外,即便您此後使用MySQL DELETE時不包含QUICK,這些索引塊也還是未充滿的,除非被刪除的索引值中有一部分碰巧位於這些未充滿的塊的之中,或與這些塊相鄰。在這些狀況下,若是要從新利用未使用的索引空間,需使用OPTIMIZE TABLE。

若是您打算從一個表中刪除許多行,使用DELETE QUICK再加上OPTIMIZE TABLE能夠加快速度。這樣作能夠從新創建索引,而不是進行大量的索引塊合併操做。

用於DELETE的MySQL惟一的LIMIT row_count選項用於告知服務器在控制命令被返回到客戶端前被刪除的行的最大值。本選項用於確保一個DELETE語句不會佔用過多的時間。您能夠只重複DELETE語句,直到相關行的數目少於LIMIT值爲止。

若是DELETE語句包括一個ORDER BY子句,則各行按照子句中指定的順序進行刪除。此子句只在與LIMIT聯用是才起做用。例如,如下子句用於查找與WHERE子句對應的行,使用timestamp_column進行分類,並刪除第一(最舊的)行:

DELETE FROM somelog  
WHERE user = 'jcole' 
ORDER BY timestamp_column  
LIMIT 1; 
您能夠在一個DELETE語句中指定多個表,根據多個表中的特定條件,從一個表或多個表中刪除行。不過,您不能在一個多表DELETE語句中使用ORDER BY或LIMIT。

table_references部分列出了包含在聯合中的表。此語法在13.2.7.1節,「JOIN語法」中進行了說明。

對於第一個語法,只刪除列於FROM子句以前的表中的對應的行。對於第二個語法,只刪除列於FROM子句之中(在USING子句以前)的表中的對應的行。做用是,您能夠同時刪除許多個表中的行,並使用其它的表進行搜索:

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; 
當搜索待刪除的行時,這些語句使用全部三個表,可是隻從表t1和表t2中刪除對應的行。

以上例子顯示了使用逗號操做符的內部聯合,可是多表MySQL DELETE語句可使用SELECT語句中容許的全部類型的聯合,好比LEFT JOIN。

本語法容許在名稱後面加.*,以便與Access相容。

若是您使用的多表MySQL DELETE語句包括InnoDB表,而且這些表受外鍵的限制,則MySQL優化程序會對錶進行處理,改變原來的從屬關係。在這種狀況下,該語句出現錯誤並返回到前面的步驟。要避免此錯誤,您應該從單一表中刪除,並依靠InnoDB提供的ON DELETE功能,對其它表進行相應的修改。

註釋:當引用表名稱時,您必須使用別名(若是已給定):

DELETE t1 FROM test AS t1, test2 WHERE ... 
進行多表刪除時支持跨數據庫刪除,可是在此狀況下,您在引用表時不能使用別名。舉例說明:

DELETE test1.tmp1, test2.tmp2 FROM test1.tmp1, test2.tmp2 WHERE ... 
目前,您不能從一個表中刪除,同時又在子查詢中從同一個表中選擇。

轉自:http://database.51cto.com/art/201005/202216.htm數據庫

相關文章
相關標籤/搜索