對MySQL DELETE語法的詳細解析

2021-06-21 06:11:09 字數 3579 閱讀 4278

此文章主要講述的是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的執行被延遲,直到沒有其它客戶端讀取本表時再執行。

刪除操作的速度會受到一些因素的影響,這些因素在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 ... 

目前,您不能從乙個表中刪除,同時又在子查詢中從同乙個表中選擇。

mysql delete的乙個問題

mysql select from a id name 1 test1 2 test2 3 test3 4 test3 5 test3 5 rows in set 0.00 sec 對這樣的乙個表,需要刪除 name相同的記錄。id沒有要求,但我這裡只留下最小的id。mysql delete fro...

MySQL DELETE 語句的乙個簡單介紹

你可以使用 sql 的 delete from 命令來刪除 mysql 資料表中的記錄。你可以在 mysql 命令提示符或 php 指令碼中執行該命令。以下是 sql delete 語句從 mysql 資料表中刪除資料的通用語法 delete from table name where clause...

access的sql語法模式對asp ado的影響

當access的資料庫儲存為ansi 89語法模式時,在access中執行查詢沒什麼問題但是在ado中會引起相當多的混亂包括 1,部分函式不能使用 2,複雜的多表連線不能使用 3,insert into select只能插入一條記錄 4,儲存過程或引數化查詢中的語法出問題,其中包括like運算子 總...