Java代码  一次delete速度异常慢的处理过程
  1. CREATE TABLE `contact784` (  
  2.     `cid` bigint AUTO_INCREMENT NOT NULL,  
  3.     `uid` bigint NOT NULL,  
  4.     `email` varchar(128) NOT NULL,  
  5.     `name` varchar(64) NOT NULL,  
  6.     `mobile` varchar(16)  NULL,  
  7.     `atime` timestamp NULL,  
  8.     `type` enum('BLACK','WHITE','NORMAL') NOT NULl default 'NORMAL',  
  9.     `info` text NULL,  
  10.     `memo` varchar(1024)  NULL,  
  11.      PRIMARY key(`cid`)  
  12. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT = 100;  
  13. ALTER TABLE `contact784` ADD UNIQUE INDEX uniq_uid_email(`uid`,`email`);  


step2,插入了100W数据: 
Java代码  一次delete速度异常慢的处理过程
  1. # -*- coding: utf-8 -*-    
  2. #@author python.han@gmail.com  
  3.   
  4. import MySQLdb  
  5. import random  
  6. import string  
  7. import threading  
  8. import time  
  9.   
  10. domains = ['org','com.cn','qq.com','yahoo.com','163.com','com','cn','sina.cn','sina.com']  
  11. host = "localhost"  
  12. user = "xx"  
  13. pwd = "xx"  
  14. db = "t3"  
  15.   
  16. def getRandomValue():  
  17.   email = ""  
  18.   s = ""  
  19.   for x in range(random.randint(1,10)):  
  20.     s += random.choice(string.letters)  
  21.   b = list(s)  
  22.   domain = ''.join(b)+"."+random.choice(domains)  
  23.   email = s+"@"+domain  
  24.   return email,s  
  25.   
  26.   
  27. def insert(count):  
  28.   conn=MySQLdb.connect(host=host,user=user,passwd=pwd,db=db)   
  29.   cursor=conn.cursor()  
  30.   for cid in xrange(count):  
  31.     uid = random.randint(1000000000,9999999999)  
  32.     email,name = getRandomValue()  
  33.     sql = "insert into contact784(uid,email,name) values (%d,'%s', '%s')" %(uid,email,name)  
  34.     n=cursor.execute(sql)   
  35.   cursor.close()  
  36.   conn.commit ()  
  37.   conn.close()  
  38.   
  39.   
  40. if __name__=='__main__':  
  41.   
  42.   start = time.clock()  
  43.   for i in range(100):  
  44.     worker = threading.Thread(target = insert(10000))  
  45.     worker.start()  
  46.   end = time.clock()  
  47.   print "elsaped:%s" %(end-start)  


step3,要重新单线程插入,需要把数据清空. 
因为python多线程由于GIL的关系,实际上上面的100个线程只产生了一个连接,需要测试一下纯单线程插入是不是要快些:) 

执行:delete from contact784 
半小时没有执行完毕! 

诊断方式: 
1,iostat ,top等查看磁盘io很大 
2,inotifywatch发现io的事件非常多 

原因:在大表上使用delete from 清空一个表是非常慢的。因为InnoDB必须处理表中的每一行,根据InnoDB的事务设计原则,首先需要把“删除动作”写入“事务日志”,然后写入实际的表。所以,清空大表的时候,最好直接drop table然后重建。 
注: 
在delete from 执行的过程中: 
用:select count(*) from contact784;发现表的数据量一直是100行 
用:explain select count(*) from contact784;可以发现数量一直在减少,显示当前 

784是是因为前面这个文章的原因“ 
http://hanyh.iteye.com/blog/431323 

相关文章: