2010-12-02 45 views
2

表的最佳方式:刪除從InnoDB表5K行與30M行

  • foreign_id_1
  • foreign_id_2
  • 整數
  • DATE1
  • DATE2
  • 初級(foreign_id_1,foreign_id_2)

查詢:delete from table where (foreign_id_1 = ? or foreign_id_2 = ?) and date2 < ?

無日期查詢大約需要40秒。這是太高:(隨着時間更加長..

的選項有:

  • create另一個表和insertselect,然後rename
  • 使用限制和查詢運行多次
  • 拆分查詢運行foreign_id_1然後foreign_id_2
  • 使用select然後單行刪除

有沒有更快的方法?


mysql> explain select * from compatibility where user_id = 193 or person_id = 193 \G 
      id: 1 
    select_type: SIMPLE 
     table: compatibility 
     type: index_merge 
possible_keys: PRIMARY,compatibility_person_id_user_id 
      key: PRIMARY,compatibility_person_id_user_id 
     key_len: 4,4 
      ref: NULL 
     rows: 2 
     Extra: Using union(PRIMARY,compatibility_person_id_user_id); Using where 
1 row in set (0.00 sec) 

mysql> explain select * from compatibility where (user_id = 193 or person_id = 193) and updated_at < '2010-12-02 22:55:33' \G 
*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: compatibility 
     type: index_merge 
possible_keys: PRIMARY,compatibility_person_id_user_id 
      key: PRIMARY,compatibility_person_id_user_id 
     key_len: 4,4 
      ref: NULL 
     rows: 2 
     Extra: Using union(PRIMARY,compatibility_person_id_user_id); Using where 
1 row in set (0.00 sec) 
+0

請在查詢中發佈`EXPLAIN`的結果。我的錢沒有足夠的索引。 – Blrfl 2010-12-02 18:46:56

+0

添加查詢說明 – zhekanax 2010-12-02 19:05:22

回答

0

現在數據量爲40M(+ 33%)並且在迅速增長。所以我開始尋找其他的一些非SQL解決方案。

謝謝。

2

在你的WHERE使得MySQL的不情願(如果不是完全拒絕)使用您user_id和/或person_id字段的索引(如果有任何一個OR - 顯示CREATE TABLE將表明,如果有是)。

如果你可以添加索引(或修改現有的,因爲我想複合索引的),我可能會添加兩個:

ALTER TABLE compatibility 
ADD INDEX user_id_updated_at (user_id, updated_at), 
ADD INDEX persona_id_updated_at (person_id, updated_at); 

相應地,假設行DELETE沒得被原子地刪除(即在同一時刻發生)。

DELETE FROM compatibility WHERE user_id = 193 AND updated_at < '2010-12-02 22:55:33'; 

DELETE FROM compatibility WHERE person_id = 193 AND updated_at < '2010-12-02 22:55:33';