于洋博客 互联网点滴记忆

23Nov/110

重置忘记的MYSQL密码

[root@jk ~]# service mysqld stop
Stopping MySQL: [ OK ]
[root@jk ~]# mysqld_safe --skip-grant-tables --skip-networking &
[1] 24688
[root@jk ~]# Starting mysqld daemon with databases from /var/lib/mysql

[root@jk ~]# mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 5.0.91-log Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> update user set password=password('******') where user='root';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 3 Changed: 0 Warnings: 0

mysql> quit
Bye
[root@jk ~]# service mysqld restart
STOPPING server from pid file /var/run/mysqld/mysqld.pid
111123 22:38:01 mysqld ended

Stopping MySQL: [ OK ]
Starting MySQL: [ OK ]
[root@jk ~]#

Filed under: Mysql No Comments
23Nov/110

死于Order By Rand()

我的某个项目里有需求从N个项目里随机抽取M个,这里我用到了Order By Rand()。
开始运作的挺好,工作表的记录数在几千左右,响应时间都马马虎虎过得去。
后来我们添加了一个功能,建了一个新表,这个表的记录会持续增加。累积了一段时间灾难爆发了,应用连接不上数据库,用mysql console,show processlist看到这种查询竟然要几秒钟。Order By Rand()用在大量记录的表上真是个灾难,而且会越来越慢。

网上搜索了一下方法,在min(id) max(id)之间生成一个随机数,然后选择大于等于这个id的M个记录即可。
SELECT * FROM `centences` AS t1 JOIN (SELECT ROUND(RAND() * ((SELECT MAX(id) FROM `centences`)-(SELECT MIN(id) FROM `centences`))+(SELECT MIN(id) FROM `centences`)) AS id) AS t2 WHERE t1.id >= t2.id ORDER BY t1.id LIMIT 1;

经过修改,问题解决。不过这个解决方案有个缺陷,假设不是LIMIT 1,会有几率导致结果比预想的少一点,这种时候就需要靠程序判断去弥补了。

另外一个问题,就是取到的是连续的记录,这个不满足我们的应用。这里依然采用循环M次的方法,每次取1。虽然执行的语句多了,但是总体执行时间还是比Order By Rand要节省很多。

Filed under: Lamp, Mysql No Comments