Mysql删除和优化很慢

时间:2013-12-20 19:32:32

标签: mysql optimization sql-delete

我搜索了Internet和Stack Overflow的麻烦,但找不到一个好的解决方案。

我有一个包含300,000行的表(MySql MyISAM)(一列是blob字段)。

我必须使用:

DELETE FROM tablename WHERE id IN (1,4,7,88,568,.......)

IN语法中有近30,000个id。

需要近1个小时。它也不会使.MYD文件变小,虽然我删除了10%,所以我运行OPTIMIZE TABLE...命令。它也持续很长时间......(我应该使用它,因为磁盘空间对我很重要)。

在删除上述数据并恢复空间时,有什么方法可以提高性能? (增加缓冲区大小?哪一个?或者?)

4 个答案:

答案 0 :(得分:2)

使用IN,MySQL将扫描表中的所有行,并将记录与IN子句进行匹配。将对IN谓词列表进行排序,数据库中的所有300,000行将针对30,000个ID进行二进制搜索。

如果在临时表上使用JOIN执行此操作(临时表上没有索引),假设id被编入索引,则数据库将在300,000记录索引上执行30,000次二进制查找。

因此,针对30,000条记录进行300,000次二进制搜索,或针对300,000条记录进行30,000次二进制搜索...哪个更快?到目前为止,第二个更快。

此外,使用DELETE QUICK延迟索引重建将导致更快的删除。所有记录都将在数据文件和索引中被标记为已删除,并且不会重建索引。

然后,要恢复空间并在以后重建索引,请运行OPTIMIZE TABLE

答案 1 :(得分:1)

IN()声明中的size of the list可能是原因。您可以将ID添加到临时表并加入以执行删除操作。此外,在使用MyISAM时,您可以使用DELETE QUICK选项来避免在删除时触发索引:

  

对于MyISAM表,如果使用QUICK关键字,则为存储引擎   在删除期间不合并索引叶子,这可能加快一些   各种删除操作。

答案 2 :(得分:1)

试试这个

  1. 使用单列id
  2. 创建一个临时表格名称
  3. 插入表1,4,7,88,568,......
  4. 使用删除加入类似
  5. 的内容
  6. DELETE ab, b FROM originaltable AS a INNER JOIN temptable AS b ON a.id= b.id where b.id is null;
  7. 这只是一个想法。查询未经过测试。你可以查看google上的语法。

答案 3 :(得分:0)

我认为使其更快的最佳方法是创建一个新表并在其中插入您不想删除的行,然后删除原始表,然后您可以将表中的内容复制到主表

这样的事情:

INSERT INTO NewTable SELECT * FROM My_Table WHERE ... ;

然后,您可以使用RENAME TABLE将副本重命名为原始名称

RENAME TABLE My_Table TO My_Table_old, NewTable TO My_Table ;

然后最后删除原始表

DROP TABLE My_Table_old;