[英]Improve performance of delete query
我想從表B中刪除條目,所以每個A_id
(ID最高的條目)只有一個條目
表A :
+----+------------+
| id | name |
+----+------------+
| 1 | Some name |
| 2 | Other name |
+----+------------+
表B :
+----+-------+------+
| id | stuff | A_id |
+----+-------+------+
| 1 | aab | 1 |
| 2 | aac | 1 |
| 3 | aad | 2 |
| 4 | aae | 1 |
| 5 | aak | 1 |
| 6 | aal | 2 |
+----+-------+------+
我當前的查詢(工作正常):
DELETE FROM B
WHERE id NOT IN (SELECT MAX(id)
FROM B
GROUP BY A_id)
得出正確的結果:
+----+-------+------+
| id | stuff | A_id |
+----+-------+------+
| 5 | aak | 1 |
| 6 | aal | 2 |
+----+-------+------+
但是當表B中有很多行時,它非常慢。是否有任何方法可以提高查詢的性能(或者可能以完全不同的方式來執行此操作?)
您正在刪除大量的行。 那就是問題所在。 刪除有很多開銷。
如果要刪除表中的大量行(並且可能只占百分之幾),則重新創建表通常會更快:
select b.*
into temp_b -- actually, I wouldn't use a temporary table in case the server goes down
from b
where b.id = (select max(a.id) from b b2 where b2.id = b.a_id);
truncate table b;
insert into b
select *
from temp_b;
嘗試執行此操作之前,請確保已備份b
或至少將其副本保存在某處。
請注意,我更改了NOT IN
的結構。 我強烈不鼓勵使用NOT IN
,因為當子查詢返回NULL
值時語義不直觀。 如果只有一個NULL
值,則WHERE
永遠不會求值為TRUE。 即使在這種情況下NULL
值不是問題,我也強烈建議您使用其他替代方法,這樣當NULL
成為可能時您就不會有問題。
為了提高SELECT
性能,您需要在b(a_id, id)
上建立索引。 您可能會發現這樣的索引有助於您的原始查詢。
您的查詢對我來說很好。
您的問題似乎是您擁有大量數據,並且需要優化性能的方法。
您可以做的是具體化您的子查詢,並確保將max_id編入索引,例如通過使其成為主鍵。
因此,創建一個臨時表Max_B
,並將子查詢的結果存儲在此表中。 然后執行刪除操作,然后刪除臨時表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.