[英]Mysql delete and optimize very slow
我在Internet和Stack Overflow上搜索了我的麻烦,但是找不到一个好的解决方案。
我有一个表(MySql MyISAM)包含300,000行(一列是Blob字段)。
我必须使用:
DELETE FROM tablename WHERE id IN (1,4,7,88,568,.......)
IN
语法中有近30,000个ID。
大约需要1个小时。 另外,尽管我删除了.MYD文件的10%,但它不会使.MYD文件变小,因此我运行OPTIMIZE TABLE...
命令。 它还持续很长时间...(我应该使用它,因为磁盘空间对我很重要)。
如上所述删除数据并恢复空间时,有什么方法可以提高性能? (增加缓冲区的大小?是哪个?还是其他?)
使用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
。
您的IN()
语句中列表的大小可能是原因。 您可以将ID添加到临时表中,然后加入进行删除。 另外,在使用MyISAM时,可以使用DELETE QUICK选项来避免在删除索引时命中索引:
对于MyISAM表,如果使用QUICK关键字,则存储引擎在删除过程中不会合并索引叶,这可能会加快某些类型的删除操作。
尝试这个
DELETE ab, b FROM originaltable AS a INNER JOIN temptable AS b ON a.id= b.id where b.id is null;
这只是一个主意。 该查询未经测试。 您可以在Google上检查语法。
我认为使速度更快的最佳方法是创建一个新表,然后将您不想删除的行插入其中,然后放下原始表,然后将内容从表复制到主表。
像这样:
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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.