[性能优化] MySQL ORDER BY RAND()的替代方案
这是开发签到助手时遇到的问题……
需求:从数据库取没有签到的TID
原来的代码:
SELECT tid FROM sign_log WHERE status IN (0, 1) AND date='{$date}' ORDER BY RAND() LIMIT 0,1
当 sign_log 这个表非常大的时候,会出现 filesort 罢工的现象
EXPLAIN 的提示:Using where; Using temporary; Using filesort
这是由于 MySQL 在执行过程中需要遍历数据库,然后给每行分配一个权重值(因为用的是RAND函数),之后再用 filesort 的方式排序临时表,最后输出。
只是取一个tid而已……有必要遍历整个表么?有没有替代的方案呢?
答案是肯定的。这个算法分为3步,将上面一个查询拆解为2个:
1.从数据库取出最大数据量:
SELECT COUNT(*) FROM `sign_log` WHERE status IN (0, 1) AND date='{$date}'
2.用 PHP 的 rand 函数计算出 offset 值
$offset = rand(1, $count) - 1;
3.直接从数据库取出这一行的tid:
SELECT tid FROM `sign_log` LIMIT {$offset},1
(再次运行时可以略过第一步)
测试结果(共13506行数据):
ORDER BY RAND():
Using where; Using temporary; Using filesort
运行时间:0.0050160884857178秒优化后:
查询1:Using where
查询2:Using index(注:tid字段有索引)
总运行时间:0.0021970272064209秒
改进后不仅提升了运行速度,还解决了 filesort 数据量上限的问题
[源码] Java简易计算器
这学期程序设计学的是Java,期末要求制作一个计算器:
花了一个晚上搞定,CalcWindow类负责界面绘制,Main类是主程序,关键代码如下:
package com.kookxiang.calc; import javax.swing.JOptionPane; public class Main { CalcWindow UI; double cur_num = 0; double prev_num = 0; boolean autoclean = false; boolean dotted = false; boolean last_equal = true; int mode = Mode.ADD; public void clear(){ cur_num = prev_num = 0; autoclean = dotted = false; last_equal = true; mode = Mode.ADD; UI.numberBox.setText("0"); } public void cal(){ boolean _last_equal = last_equal; last_equal = true; String txt=UI.numberBox.getText(); if(!_last_equal) eval(); switch(mode){ case Mode.ADD: prev_num = prev_num + cur_num; break; case Mode.MINUS: prev_num = prev_num - cur_num; break; case Mode.MUILTIPLY: prev_num = prev_num * cur_num; break; case Mode.DIVISION: prev_num = prev_num / cur_num; break; } txt = prev_num+""; UI.numberBox.setText(txt); http:// 消掉结尾的 *.0 if(txt.endsWith(".0")) UI.numberBox.setText(txt.substring(0, txt.length()-2)); autoclean = true; if(Double.isNaN(prev_num) || Double.isInfinite(prev_num)){ clear(); JOptionPane.showMessageDialog(null, "发生未知错误"); } } public void eval(){ if(!last_equal) cal(); prev_num = cur_num; dotted = false; autoclean = true; cur_num = Double.parseDouble(UI.numberBox.getText()); } public void onCreate(String[] flags){ UI = new CalcWindow(this); clear(); } public static void main(String[] args) { new Main().onCreate(args); } public void handleAction(String command) throws Exception { String txt=UI.numberBox.getText(); if(txt.equals("0")) txt = ""; switch(command){ case "exit": System.exit(0); break; case "clear": clear(); break; case "backspace": if(txt.isEmpty()) return; if(autoclean){ UI.numberBox.setText(""); autoclean = false; return; } UI.numberBox.setText(txt.substring(0, txt.length()-1)); break; case "dot": if(dotted) return; dotted = true; command = "."; case "1": case "2": case "3": case "4": case "5": case "6": case "7": case "8": case "9": case "0": case ".": UI.numberBox.setText(autoclean ? command : txt + command); autoclean = false; last_equal = false; break; case "dn": if(txt.isEmpty()) return; if(txt.substring(0, 1).equals("-")){ UI.numberBox.setText(txt.substring(1)); }else{ UI.numberBox.setText("-"+txt); } break; case "add": if(txt.isEmpty()) return; eval(); mode = Mode.ADD; break; case "minus": if(txt.isEmpty()) return; eval(); mode = Mode.MINUS; break; case "multiply": if(txt.isEmpty()) return; eval(); mode = Mode.MUILTIPLY; break; case "division": if(txt.isEmpty()) return; eval(); mode = Mode.DIVISION; break; case "cal": cal(); break; default: throw new Exception("Unknown command"); } } }
完整源代码下载:Calculator.rar
【汉化】Yet Another Aria2 Web Frontend
先介绍下Aria2(摘自http://wiki.ubuntu.org.cn):
Aria2是一个命令行下运行、多协议、多来源下载工具(HTTP/HTTPS、FTP、BitTorrent、Metalink),内建 XML-RPC 用户界面。
既然是命令行下工作的,那么管理必然是一个难题,好在它提供了JSON-RPC的功能,也就有了Web管理界面
YAAW算是所有管理界面中最简洁、清爽的了,源地址在这里:https://github.com/binux/yaaw
看了网上很多汉化版,没有自己满意的。
要么汉化不完整,要么相关术语翻译不准确,让人听起来不知所云
于是自己动手汉化了下,反正都是HTML和JS,汉化难度也不大:
汉化后的项目:https://github.com/kookxiang/yaaw
另外:本人有严重洁癖,所以将网址中的###去掉了……
[续] 一键检测QQ群重复成员
上一篇《清理两个QQ群中的重复成员》发布后,Coxxs 童鞋给出了一个Anti-CSRF参数的算法,于是趁着周末又更新了一下。
这回全部用js实现了,使用方法如下:
拖放“搜索QQ群重复成员”到你的收藏夹
登陆QQ群空间 qun.qq.com
点击书签,按提示选择即可
失落的圣诞节
嗯,今天是2012年的圣诞节,听到2012和圣诞节就想到了这作品……
《罪恶王冠:失落的圣诞节》是动画《罪恶王冠》的外传。所以要是你没看过Guilty Crown这部神作的话还是先看了再玩会比较好。下载地址:
磁力链接下载 (请保证安装了迅雷或其他支持磁力链接的下载工具!)
游戏中的时间追溯到了动画版的10年前,突然其来的致命病毒Apocalypse Virus 开始蔓延,这也让日本政府陷入混乱并丧失身为政府的主要机能,此一事件即后来被称为Lost Christmas 的历史灾害。
但在鲜为人知的背后却有着另一段的故事,而游戏描写的就是Scrooge与Carol两人在这个时候鲜为人知的另一段大活跃故事。
下载:http://kuai.xunlei.com/d/GRGPOHGTMEFY
密码:四散的尘埃
游戏分级:15+
迅雷7 精简助手 v1.0 测试版
本人制作的一款迅雷7精简助手,其支持迅雷7系列的所有版本,程序自动搜索迅雷目录,精简组件,精简下来的内容会自动备份,您可以在addins_backup中找到它们
鉴于此版本为测试版,故需要序列号,前几位评论者可以获得序列号。公测版中将取消序列号系统。
下载地址: http://u.115.com/file/f4d0e0a8b9
ps: 下个版本可能会增加屏蔽广告的…
来自 Android 版 WordPress.