mysql 删除表中的重复记录
[ 2009/07/31 20:53 | by selboo ]
MySQL中漏掉了40%左右的数据,寻找这个错误的代价是花了三天,将所有的代码重新检查了一遍,由于代码不是我写的,看得晕头转向,上苍保佑,我还不算太笨,最终找到了原因,不过接着就碰到另外一个问题,找回的数据中存在重复,而且在无法在重复的健上建立唯一,于是我想了一个最笨的方法
这种算法是最傻也是最没出息的算法,在数量在1W的时候还可以接受,到10W就要两分钟了,到50W就死在那里了,所以告诫那些跟我一样天资不算聪明的人,数据量比较大的时候千万别用这种方法,这种类似冒泡排序的算法复杂度是O(n^2),如果你有10W条记录,你自己乘一下吧
接着又想了另外一个方法,虽然机械了点,不过效率非常之高,分三步走:
10W条记录,在第一步处理师大约为4秒,50w条记录时为19秒左右,再往上就没测了
后面两条语句纯粹是体力活,如果你用的是phpadmin,点点鼠标就可以搞定
SELECT * FROM sub_new WHERE email IN (
SELECT email FROM sub_new
GROUP BY email HAVING count(email) > 1
)
SELECT email FROM sub_new
GROUP BY email HAVING count(email) > 1
)
这种算法是最傻也是最没出息的算法,在数量在1W的时候还可以接受,到10W就要两分钟了,到50W就死在那里了,所以告诫那些跟我一样天资不算聪明的人,数据量比较大的时候千万别用这种方法,这种类似冒泡排序的算法复杂度是O(n^2),如果你有10W条记录,你自己乘一下吧
接着又想了另外一个方法,虽然机械了点,不过效率非常之高,分三步走:
CREATE TABLE tmp AS SELECT * FROM youtable
GROUP BY name
DROP TABLE youtable
ALTER TABLE tmp RENAME youtable
GROUP BY name
DROP TABLE youtable
ALTER TABLE tmp RENAME youtable
10W条记录,在第一步处理师大约为4秒,50w条记录时为19秒左右,再往上就没测了
后面两条语句纯粹是体力活,如果你用的是phpadmin,点点鼠标就可以搞定
df和du显示空间为何不一致
[ 2009/07/30 12:02 | by selboo ]
有台机器空间老是显示满,df显示已经使用了100%,可用du命令却没见占用很多空间,后来终于在网上查到了原因所在:
造成这个现象的原因是有进程仍然打开着已经被删除的文件。因为该文件已经不存在于文件目录树上,所以du遍历整个文件系统中不会统计其所占用的空间,可是,这个文件又还不能被从磁盘上删除,所以确实还占用了一部分磁盘空间。
可以用lsof来确定究竟是哪个进程搞的鬼,比如:
上面这个例子显示tail(pid为31818)进程打开了一个已经被删除的文件(/var/spool/clientmqueue/dfm9TAh6du031818 ),这个文件大小为457053。此时,如果终止这个进程,那么这457053多字节就会正常释放,df的输出也就和du一致了。
曾经遇到过此类问题的报告,似乎杀了sendmail就好了。当时不知原由,现在想来,可能是系统长时间运行后sendmail的日志经过了rotate,而sendmail仍然打开着旧的日志文件。
以后再遇到此类情况,直接用lsof命令,查看是哪些进程占用着已删除文件,就可相机处理了。
造成这个现象的原因是有进程仍然打开着已经被删除的文件。因为该文件已经不存在于文件目录树上,所以du遍历整个文件系统中不会统计其所占用的空间,可是,这个文件又还不能被从磁盘上删除,所以确实还占用了一部分磁盘空间。
可以用lsof来确定究竟是哪个进程搞的鬼,比如:
# lsof | grep deleted
sendmail 31818 hsq 3uW REG 8,5 194523136 457053 /var/spool/clientmqueue/dfm9TAh6du031818 (deleted)
sendmail 31818 hsq 3uW REG 8,5 194523136 457053 /var/spool/clientmqueue/dfm9TAh6du031818 (deleted)
上面这个例子显示tail(pid为31818)进程打开了一个已经被删除的文件(/var/spool/clientmqueue/dfm9TAh6du031818 ),这个文件大小为457053。此时,如果终止这个进程,那么这457053多字节就会正常释放,df的输出也就和du一致了。
曾经遇到过此类问题的报告,似乎杀了sendmail就好了。当时不知原由,现在想来,可能是系统长时间运行后sendmail的日志经过了rotate,而sendmail仍然打开着旧的日志文件。
以后再遇到此类情况,直接用lsof命令,查看是哪些进程占用着已删除文件,就可相机处理了。
php的memcache模块的优化
[ 2009/07/28 15:14 | by selboo ]
memcache.allow_failover = 1
memcache.max_failover_attempts=20
memcache.chunk_size =8192
memcache.default_port = 11211
memcache.max_failover_attempts=20
memcache.chunk_size =8192
memcache.default_port = 11211
其中比较重要的是
memcache.chunk_size
一个整型值,用于控制数据传输的大小。默认值为 8192 字节 (8 KB),但是如果设置为 32768 (32 KB),则可以获得更好的性能。
memcache.allow_failover
一个布尔值,用于控制当连接出错时 Memcache 扩展是否故障转移到其他服务器上。默认值为 1 (true)。
memcache.max_failover_attempts
一个整型值,用于限制连接到持久性数据或检索数据的服务器数目。如果 memcache.allow_failover 为 false,则将忽略此参数。默认值为 20。
memcache.default_port
另一个整型值,用于设置连接到 Memcache 所使用的 TCP 端口。除非您修改它,否则默认值为无特权的高端口 11211。
对于访问量非常大的服务器,最好是通过socket来连接memcached,这样能减少打开和关闭tcp/ip链接的开销。
如果memcached和php在两台不同的服务器上,通过udp来连接应该比tcp连接能消耗小一些,并且能获得更好的速度(尚未测试)
在memcached中启用压缩,对于通过tcp/ip 或者udp连接的memcache,能减少传输数据的大小,也能相应的降低一些负载
1.练习文件
cat datafile
northwest NW Charles Main 3.0 .98 3 34
northern WE Sharon Cray 5.3 .97 5 23
southnorth SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Particia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .7 4 20
northeast NE am Main JR. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
wangdongsheng ST Neu Soft 8.8 .77 6 5
2. sed '/north/p' datafile
默认情况下sed会打出全部的,如果在某一行匹配到模式north ,sed会多打一遍此行.
3. sed -n 'north/p' datafile
-n 与p命令配合使用,sed 取消了sed的缺省打印动作,如果不指定n这个选项,
sed就会从复打印north选项,如果指定了n就只打印模式north的那几行.
4. sed '3d' datafile
d命令就是删除第3行内容。
5.sed'3,$d' datafile
删除第3行到最后一行的内容。
6. sed '$d' datafile
删除最后一行.
7. sed '/north/d' datafile
删除包含所有行的north;其他的打印出来
8.sed 's/west/north/g'
把所有的west替换成north
9.sed -n 's/^west/north/p' datafile
搜索行首带west的行,并将替换为north,并打印出来
10.sed 's/[0-9][0-9]$/&.5/' datafile
与符号(&)在替换穿中时,代表查找串中匹配内容。这个例子中以两位数字结尾的行后面都被加上.5如果要在替换串中表示“与”号字面的含义,就要对起进行转义,记为:\&
11. sed -n 's/Hemenway/Jones/gp' datafile
文件中出现所有Hemenway都被替换为Jones,唯一发生变化的行被打印.选项-n与p的组合取消了缺省的输出,标志g含义在行内进行全局替换。
12. sed -n 's/\(Mar\)got/\lianne/p' datafile
扩在括号里的模式Mar作为标签1被保存与特殊寄存器中,替换串通、1引用它,Margot被替换为Marianne.
13. sed 's#3#88#g' datafile
紧跟在S命令的字符是查找和替换之间的分隔符。分隔符缺省的正斜杠,但可以改变(只在使用s命令时).无论什么字符,只要紧跟着s命令就成新的串分隔符,这个方法在查找包含正斜杠的模式时很管用,例如查找路径名和生日.
14. sed -n '/west/,/east/p' datafile
打印在west和east之间的所有行,如果west出现在east之后的某一行,则打印的范围从west所在行开始,到下一个出现east的行或文件末尾。
15. sed -n '5,/^northeast/p' datafile
打印前5行到第一个以northeast开头的行之间的所有行.
16 '/west/,/east/s/$/***WANGDONGSHENG***/' datafile
修改模式east和west之间的所有行,将各行的行尾($)替换为字符串***WANGDONGSHENG***换行符号被移动到这个新的字符串后面,箭头标出了范围.
17. sed -e '1,3d' -e 's/Hemenway/Jones' datafile
-e的作用是先删除1到3行,然后把Hemenway替换Jones,因为这是逐行编辑的(即两个命令都在模式空间上执行),所以编辑的顺序会影响结果.例如如果两条命令都是执行替换,则前一行替换会影响后一行.
18.sed -n '/north/w newfile' datafile
w命令是把指定写入文件。文件datafile中所有包含模式north的行都写到文件newfile中
19.sed '/^north /a\\---->the north sales district has moved<---' datafile
a为追加命令,字符串the north sales district has moved被加在以north开头,north
后跟一空格的各行之后,用于追加文本必须出现在追加命令下一行上.
20.sed '/eastern/i\\NEW REGLAND REGION\\---------------------------' datafile
i命令是插入命令。如果某一行匹配到模式eastern,i命令就在该行上放插入命令中反斜
杠后的文本,除了最后一行,用于插入文本中每一行都必须以反斜杠结尾
21.sed '/eastern/{ n; s/AM/Archie/; }' datafile
如果在某一行匹配到模式eastern,n命令就是指sed用下一个输入行(即包括AM Main Jr 的那行)
替换模式空间中的当前行,用Archie替换(s)其中的AM,然后打印
22. sed'1,3y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ' datafile
y命令把第一到第3行所有小写字母换成大写字母。正则表达式对y不起作用.
23 sed '5q' datafile
打印第5行之后,q命令让sed程序退出
24 'Lewis/{ s/Lewis/Joseph/;q; }' datafile
在某行匹配模式到Lewis时,先用Joseph替换(s)Lewis然后q命令退出
25 sed -e '/northeast/h' -e '$G' datafile
如果在某一行找到模式WE,h命令就将该行从模式缓冲区拷贝到一个暂存的缓冲区
保存在暂存缓冲区的行可以在以后被重新取出(使用命令G或g),这个例子中,当模式WE
被找到时将模式缓冲区的那份拷贝删除,
26.sed -e '/WE/{h; d; }' -e '/CT/{G; }' datafile
sed处理文件时,会把文件每一行都保存在一个临时的缓冲区中,这个缓冲区会被称为模式空间。sed处理每一行后,都会将其打印在屏幕上,除非该行被删除会被取消。之后模式空间清空,下一输入行等待处理。本例子中,被包含的模式northeast的行被找到之后,就被保存在模式空间里h命令把复制并保存到另一个缓冲区,这个特殊的缓冲区是暂存的缓冲区(holding buffer)在第二条sed命令中,sed读到最后一行($)时,G命令指示它从暂存缓冲区读出一行,将其放回模式缓冲区,追加在模式空间内当前行(本例中是最后一行)的后面
sed 's/^[]*//g' filename
sed 's/^ *//g' filename
sed 's/^[[:space:]]*//g' filename
删除以.结尾行 s/^.$//g
删除以一个以上空格,用一个空格代替 s/[][][]*/[]/g
删除空行 /^$/d
删除第一个字符 s/^.//g
删除所有空格并用Tab键代替 s/[]/[ ]//g
删除行首所有Tab键 s/^[ ]//g
删除所有Tab键 s/[ ]*//g
cat datafile
northwest NW Charles Main 3.0 .98 3 34
northern WE Sharon Cray 5.3 .97 5 23
southnorth SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Particia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .7 4 20
northeast NE am Main JR. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
wangdongsheng ST Neu Soft 8.8 .77 6 5
2. sed '/north/p' datafile
默认情况下sed会打出全部的,如果在某一行匹配到模式north ,sed会多打一遍此行.
3. sed -n 'north/p' datafile
-n 与p命令配合使用,sed 取消了sed的缺省打印动作,如果不指定n这个选项,
sed就会从复打印north选项,如果指定了n就只打印模式north的那几行.
4. sed '3d' datafile
d命令就是删除第3行内容。
5.sed'3,$d' datafile
删除第3行到最后一行的内容。
6. sed '$d' datafile
删除最后一行.
7. sed '/north/d' datafile
删除包含所有行的north;其他的打印出来
8.sed 's/west/north/g'
把所有的west替换成north
9.sed -n 's/^west/north/p' datafile
搜索行首带west的行,并将替换为north,并打印出来
10.sed 's/[0-9][0-9]$/&.5/' datafile
与符号(&)在替换穿中时,代表查找串中匹配内容。这个例子中以两位数字结尾的行后面都被加上.5如果要在替换串中表示“与”号字面的含义,就要对起进行转义,记为:\&
11. sed -n 's/Hemenway/Jones/gp' datafile
文件中出现所有Hemenway都被替换为Jones,唯一发生变化的行被打印.选项-n与p的组合取消了缺省的输出,标志g含义在行内进行全局替换。
12. sed -n 's/\(Mar\)got/\lianne/p' datafile
扩在括号里的模式Mar作为标签1被保存与特殊寄存器中,替换串通、1引用它,Margot被替换为Marianne.
13. sed 's#3#88#g' datafile
紧跟在S命令的字符是查找和替换之间的分隔符。分隔符缺省的正斜杠,但可以改变(只在使用s命令时).无论什么字符,只要紧跟着s命令就成新的串分隔符,这个方法在查找包含正斜杠的模式时很管用,例如查找路径名和生日.
14. sed -n '/west/,/east/p' datafile
打印在west和east之间的所有行,如果west出现在east之后的某一行,则打印的范围从west所在行开始,到下一个出现east的行或文件末尾。
15. sed -n '5,/^northeast/p' datafile
打印前5行到第一个以northeast开头的行之间的所有行.
16 '/west/,/east/s/$/***WANGDONGSHENG***/' datafile
修改模式east和west之间的所有行,将各行的行尾($)替换为字符串***WANGDONGSHENG***换行符号被移动到这个新的字符串后面,箭头标出了范围.
17. sed -e '1,3d' -e 's/Hemenway/Jones' datafile
-e的作用是先删除1到3行,然后把Hemenway替换Jones,因为这是逐行编辑的(即两个命令都在模式空间上执行),所以编辑的顺序会影响结果.例如如果两条命令都是执行替换,则前一行替换会影响后一行.
18.sed -n '/north/w newfile' datafile
w命令是把指定写入文件。文件datafile中所有包含模式north的行都写到文件newfile中
19.sed '/^north /a\\---->the north sales district has moved<---' datafile
a为追加命令,字符串the north sales district has moved被加在以north开头,north
后跟一空格的各行之后,用于追加文本必须出现在追加命令下一行上.
20.sed '/eastern/i\\NEW REGLAND REGION\\---------------------------' datafile
i命令是插入命令。如果某一行匹配到模式eastern,i命令就在该行上放插入命令中反斜
杠后的文本,除了最后一行,用于插入文本中每一行都必须以反斜杠结尾
21.sed '/eastern/{ n; s/AM/Archie/; }' datafile
如果在某一行匹配到模式eastern,n命令就是指sed用下一个输入行(即包括AM Main Jr 的那行)
替换模式空间中的当前行,用Archie替换(s)其中的AM,然后打印
22. sed'1,3y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ' datafile
y命令把第一到第3行所有小写字母换成大写字母。正则表达式对y不起作用.
23 sed '5q' datafile
打印第5行之后,q命令让sed程序退出
24 'Lewis/{ s/Lewis/Joseph/;q; }' datafile
在某行匹配模式到Lewis时,先用Joseph替换(s)Lewis然后q命令退出
25 sed -e '/northeast/h' -e '$G' datafile
如果在某一行找到模式WE,h命令就将该行从模式缓冲区拷贝到一个暂存的缓冲区
保存在暂存缓冲区的行可以在以后被重新取出(使用命令G或g),这个例子中,当模式WE
被找到时将模式缓冲区的那份拷贝删除,
26.sed -e '/WE/{h; d; }' -e '/CT/{G; }' datafile
sed处理文件时,会把文件每一行都保存在一个临时的缓冲区中,这个缓冲区会被称为模式空间。sed处理每一行后,都会将其打印在屏幕上,除非该行被删除会被取消。之后模式空间清空,下一输入行等待处理。本例子中,被包含的模式northeast的行被找到之后,就被保存在模式空间里h命令把复制并保存到另一个缓冲区,这个特殊的缓冲区是暂存的缓冲区(holding buffer)在第二条sed命令中,sed读到最后一行($)时,G命令指示它从暂存缓冲区读出一行,将其放回模式缓冲区,追加在模式空间内当前行(本例中是最后一行)的后面
sed 's/^[]*//g' filename
sed 's/^ *//g' filename
sed 's/^[[:space:]]*//g' filename
删除以.结尾行 s/^.$//g
删除以一个以上空格,用一个空格代替 s/[][][]*/[]/g
删除空行 /^$/d
删除第一个字符 s/^.//g
删除所有空格并用Tab键代替 s/[]/[ ]//g
删除行首所有Tab键 s/^[ ]//g
删除所有Tab键 s/[ ]*//g
cat -e test.txt 是不是有出现^M 这样的字符(windows换行符)
有的话先sed 's/\r//' -i test.txt
再执行
paste -d ' ' test.txt test1.txt
或用
unix2dox
有的话先sed 's/\r//' -i test.txt
再执行
paste -d ' ' test.txt test1.txt
或用
unix2dox