scourgen

13一/100

MySQL性能调优 – 使用更为快速的算法进行距离计算

最近遇到了一个问题,通过不断的尝试最终将某句原本占据近1秒的查询优化到了0.01秒,效率提高了100倍.

问题是这样的,有一张存放用户居住地点经纬度信息的MySQL数据表,表结构可以简化为:id(int),longitude(long),latitude()long. 而业务系统中有一个功能是查找离某个用户最近的其余数个用户,通过代码分析,可以确定原先的做法基本是这样的:

//需要查询的用户的坐标

$lat=20;
$lon=20;
//执行查询,算出该用户与所有其他用户的距离,取出最近的10个
$sql='select * from users_location order by ACOS(SIN(('.$lat.' * 3.1415) / 180 ) *SIN((latitude * 3.1415) / 180 ) +COS(('.$lat.' * 3.1415) / 180 ) * COS((latitude * 3.1415) / 180 ) *COS(('.$lon.' * 3.1415) / 180 - (longitude * 3.1415) / 180 ) ) * 6380  asc limit 10';

而这条sql执行的速度却非常缓慢,用了近1秒的时间才返回结果,应该是因为order里的子语句用了太多的数学计算公式,导致整体的运算速度下降.

而在实际的使用中,不太可能会发生需要计算该用户与所有其他用户的距离,然后再排序的情况,当用户数量达到一个级别时,就可以在一个较小的范围里进行搜索,而非在所有用户中进行搜索.

所以对于这个例子,我增加了4个where条件,只对于经度和纬度大于或小于该用户1度(111公里)范围内的用户进行距离计算,同时对数据表中的经度和纬度两个列增加了索引来优化where语句执行时的速度.

最终的sql语句如下:

$sql='select * from users_location where
latitude>'.$lat.'-1 and
latitude<'.$lat.'+1 and
longitude>'.$lon.'-1 and
longitude<'.$lon.'+1
order by ACOS(SIN(('.$lat.' * 3.1415) / 180 ) *SIN((latitude * 3.1415) / 180 ) +COS(('.$lat.' * 3.1415) / 180 ) * COS((latitude * 3.1415) / 180 ) *COS(('.$lon.' * 3.1415) / 180 - (longitude * 3.1415) / 180 ) ) * 6380  asc  limit 10';

经过优化的sql大大提高了运行速度,在某些情况下甚至有100倍的提升.这种从业务角度出发,缩小sql查询范围的方法也可以适用在其他地方.

12一/100

MySQL性能调优 – 使用UNION ALL代替UNION

最近遇到了一个MySQL性能调优的问题,在数据库中有一张主要用了2个UNION来联合3张表的视图,而所有对于这个视图的查询反应都很慢,经过一步步的调试(说句题外话,用SQLYog来调试MySQL真的很方便),最终确定问题出在这个视图里所用的UNION上。

查了查MySQL的文档,这么说到

The default behavior for UNION is that duplicate rows are removed from the result. The optional DISTINCT keyword has no effect other than the default because it also specifies duplicate-row removal. With the optional ALL keyword, duplicate-row removal does not occur and the result includes all matching rows from all the SELECT statements.

You can mix UNION ALL and UNION DISTINCT in the same query. Mixed UNION types are treated such that a DISTINCT union overrides any ALL union to its left. A DISTINCT union can be produced explicitly by using UNION DISTINCT or implicitly by using UNION with no following DISTINCT or ALL keyword.

举个例子:

如果union两个不同的select,最终的结果则是2个select的集合:

select 1 union select 2;
+---+
| 1 |
+---+
| 1 |
| 2 |
+---+
2 rows in set (0.00 sec)

而如果union的对象包含重复的数据,例如下条语句包含了两个select 2,默认则会去除重复部分:

select 1 union select 2 union select 2;
+---+
| 1 |
+---+
| 1 |
| 2 |
+---+
2 rows in set (0.00 sec)

而如果将上条语句改为union all的话,则可以显示所有的结果,包含重复部分:

select 1 union all select 2 union all select 2;
</strong>+---+
| 1 |
+---+
| 1 |
| 2 |
| 2 |
+---+
3 rows in set (0.00 sec)

可以看到,union和union all的差别就在于union会对数据做一个distanct的动作,而这个distanct动作的速度则取决于现有数据的数量,数量越大则时间也越慢。而对于几个数据集,要确保数据集之间的数据互相不重复,基本是O(n)的算法复杂度。

有了理论依据后,便动手更改view的结构,在确保数据逻辑上不会有重复情况出现后,将2个union都改成了union all,query的反应速度从1.7秒变成了300毫秒左右,耗费时间只有以前的17%。

12一/101

Apple store的真实收入

最近看到一些新闻,标题是《Gameloft:18 个月,1000 万次付费下载》

比如 Gameloft,在其美国时间 1 月 7 日发布的新闻稿中,其董事长兼 CEO Michel Guillemot 宣布它已经获得了1000 万付费下载。按 Gameloft 的游戏大多分布在 4.99 到 6.99 的价格计,它在 18 个月内获得 5000 万美元的收入是不成问题的。

平均售价6美金,1000万次付费下载,收入是否真的就等于5000万美元?

这不是一个简单的乘法。

Scourgen的朋友Jacky曾经是苹果的粉丝,他曾经告诉我有一种gift card可以在淘宝上买到,这种gift card可以用rmb购买,再兑换成购买价格几十倍的app store内的美金。于是我在淘宝上以“app store”为关键字进行了搜索,搜索结果竟然有1119条,而多数宝贝都是以35人民币的价格贩卖100美金的充值面额,也就是说你花35人民币,以原来5%的价格(35人民币 除以 (6.8汇率 乘以 100美金) =5.15%),就可以在app store上买总计100美金的应用程序,如果算做5美金一个应用程序的话,则可以用35元买20个应用程序,折合每个1.75元。花2块钱不到买一个在iphone上运行的正版软件,真是非常吸引人的事情,难怪scourgen随便打开几个宝贝,发现每个宝贝的成交都有10个以上,看来好多人已经用这种方法去购买app store内的软件了。

我想,任何一个人如果知道可以通过这种方法以低价购买app,他们肯定不会继续以20倍的价格继续购买app了吧?

做一个悲观的假设,如果所有购买gameloft的app的用户都使用这种方法进行购买,则gameloft真实的收入是多少呢?1000万次付费下载,每次1.75元(0.26美元),则是260万美元。260万美元,看起来还真不少,等等,你忘记了apple!因为根据app store与应用程序开发商的协议,所有程序销售额的30%均需要给apple分成,所以gameloft拿可怜的260万美金收入还得打7折,也就是182万美元。

新闻稿的5000万美元和182万美元之间可是差太多了,这是否代表着现在的app store并没有想象中的那么美好?做iphone程序可能真的不怎么赚钱。

分类: IT 1个评论
12一/100

6款PHP论坛大比拼之 性能比较

因为工作需要,需要在现有的网站上部署一个论坛以供用户使用,所以对目前较为著名的6款php论坛进行了一个评测.

这6款论坛分别是:
phpBB v3
bbPress 1.0
phorum 5.2.14
vanilla 1.1.10
IP.Board v3.0.4
vBulletin Suite (VBB) v4

而之所以没有考虑phpwind,discuz等国内著名论坛,主要是因为语言支持和安全方面的考虑.

在测试之前,我已经将6款forum的最新版本安装到了我的MacBook Pro上,用MAMP作为服务程序,提供一个统一软件的平台.

安装完之后,先进行一下简单的性能测试:

#ab -n 100000 -c 100 $url

name     xcache     apc

phpbb3 152  113

bbpress 45  50

phorum 184 189

vanilla 119 125

ipb 64 60

vbb 59 56

可以看到速度最快的是phorum,可是phorum提供的功能确不够充分,属于短小精悍形的论坛程序,如果您的需求只是速度至上,那么phorum应该是你的不二选择。

在这里必须表扬一下vbb,vbb在严苛的功能需求和性能之间做到了完美的平衡,虽然它是历史最悠久,功能最强大的论坛之一,但是运行速度却丝毫不差前几位轻量级选手,我用xcache观察到vnn在处理论坛默认页时只include了15个文件,而耗费的内存不超过3m,这在php程序里可以算是大型程序一个优化到极致的典型了吧!

所以关于性能上的选择,如果还是需要考虑到兼备功能的话,scourgen强力推荐vbb,否则可以考虑phpbb3以及vanilla,而如果您追求极致的速度,phorum则是你的不二之选。

分类: php 没有评论
13十二/090

解决ofbiz在MAC下出现Keystore密码错误的问题

报错信息:

2009-12-13 13:55:01,489 (main) [            SSLImpl.java:63 :ERROR]
---- exception report ----------------------------------------------------------
Exception: java.io.IOException
Message: Keystore was tampered with, or password was incorrect
---- cause ---------------------------------------------------------------------
Exception: java.security.UnrecoverableKeyException
Message: Password verification failed
---- stack trace ---------------------------------------------------------------
java.security.UnrecoverableKeyException: Password verification failed
sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:769)
sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:38)
java.security.KeyStore.load(KeyStore.java:1185)
org.ofbiz.base.util.KeyStoreUtil.getSystemTrustStore(KeyStoreUtil.java:110)
org.ofbiz.base.util.SSLUtil.getTrustManagers(SSLUtil.java:106)
org.ofbiz.catalina.container.SSLImpl$AllowTrustManager.<init>(SSLImpl.java:61)
org.ofbiz.catalina.container.SSLImpl.<init>(SSLImpl.java:46)
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
java.lang.reflect.Constructor.newInstance(Constructor.java:513)
java.lang.Class.newInstance0(Class.java:355)
java.lang.Class.newInstance(Class.java:308)
org.apache.tomcat.util.net.SSLImplementation.getInstance(SSLImplementation.java:75)
org.apache.coyote.http11.Http11Protocol.init(Http11Protocol.java:152)
org.apache.catalina.connector.Connector.initialize(Connector.java:1058)
org.apache.catalina.core.StandardService.initialize(StandardService.java:677)
org.ofbiz.catalina.container.CatalinaContainer.init(CatalinaContainer.java:218)
org.ofbiz.base.container.ContainerLoader.loadContainer(ContainerLoader.java:188)
org.ofbiz.base.container.ContainerLoader.load(ContainerLoader.java:65)
org.ofbiz.base.start.Start.initStartLoaders(Start.java:259)
org.ofbiz.base.start.Start.init(Start.java:96)
org.ofbiz.base.start.Start.main(Start.java:410)
--------------------------------------------------------------------------------

其实是因为在mac下,java 1.6的cacerts默认密码从以前的"changeit"变成了"changeme"

可以用如下办法恢复密码:

cd  #cd ~
#keytool -importkeystore -srckeystore /System/Library/Frameworks/JavaVM.framework/Versions/A/Resources/Deploy.bundle/Contents/Home/lib/security/cacerts -destkeystore newcacerts
Enter destination keystore password: changeit
Re-enter new password: changeit
Enter source keystore password:              #直接回车,留空
#sudo mv newcacerts /System/Library/Frameworks/JavaVM.framework/Versions/A/Resources/Deploy.bundle/Contents/Home/lib/security
#sudo mv cacerts oldcacerts
#sudo mv newcacerts cacerts

就ok啦

分类: Java 没有评论
3十二/090

一个改进网上花店的构思

我有几个朋友经常在网上买花送人,一为方面,二为价格便宜,在网上多逛逛总能找到中意的花店.可是多半花店最终送的花却和照片效果千差万别.

而现在网上花店大概分两种,

  1. 独立的网上商店,使用ecshop或shopx之类的开店软件,花被当成了普通商品一样进行出售.
  2. 在B2C网站上开店,例如淘宝和易趣.

而一般网上送花的流程如下:

  1. 在网站上按照图片选花(用户A:)
  2. 付费(用户A)
  3. 约定送花时间和收花人(用户A,网站)
  4. 到约定日期,包装花朵,送花(网站)
  5. 签收(用户B)
  6. 对商品进行评价(用户A,用户B)

花并不是纯粹意义上的商品,花代表了一种感情.如果在买花的过程中发生质量问题,将会非常大的影响到用户体验.试想一下如果送花给情人或老婆,花了大价钱最终她却得到的是几朵快要凋谢的玫瑰,可能两人感情都会受此印象而降低几分.

而目前这样的商业流程其实有2个问题,那就是

  1. 用户在选购的时候有一定的盲目性,只能按照图片的样子,或是销量,或是价格来选花.
  2. 花不像一般商品通过流水线制造出来,有一定的保修期,即使坏了或质量不满意可以退换.花在递送给收货人后,也就是消费过程结束后,买家才能得到产品质量的反馈,而在此之前,没有人能够保证花的质量,用户在选购花的时候也没有办法知道将要送的花会是什么样子的.

如果店家能够将每次成功交易并要送的花在送之前拍照,并上传到网站上,同时写上买花人和送花人的关系,送花致词等等信息作为其他用户选购的参考,则可以很简单的解决这个问题.

如果有了这个功能,其他买家就可以通过送花记录查看花以前被送的样子,通过各种买花人与送花人的关系,致词作为参考来挑选自己喜欢的花,各位花痴也能够从送花记录了解到哪些花适合用来送给那类人,把玫瑰送给老师的故事就再也不会发生了.

而如果对这个功能稍加改进,则可以将其做成一个web2.0风格的留言系统,买花人可以在这个页面上留下自己的文字,想说的话,甚至视频,而收花人收到花后通过特定的网址进入网站,可以一边捧着花一边享受这感人的时刻.这时花才真正完成了他的使命.

分类: Idea 没有评论
3十二/090

什么是ViViPOS

ViViPOS是一个价格低但功能强大的POS收银机.

ViViPOS的目标市场是中低端价格,但是功能强大的收银机.它的中低端价格体现在:将条码打印机,收银软件,收银硬件(主机),钱箱这收银四大件作为一体化解决方案打包出售,免费的收银软件和一体化的嵌入式硬件设计将它的成本控制在了较低的水平.
而较低的成本在ViViPOS上却不代表功能的缺乏,ViViPOS以Ubuntu作为操作平台,使用XULRunner作为应用程序开发平台,使用SQLite数据库,配合ViViPOS上的专有开发SDK,在达到完全面License费用的同时,提供了强大的应用程序开发和扩展能力.
ViViPOS主要特色

ViViPOS是一个智能终端

ViViPOS并不是单一的收银软件,在现有的ViViPOS扩展中,不但包含各种扩展插件,例如跑马灯公告,网络设置,打印发票模板,虚拟键盘等等,在外部扩展上更已经可以支持CakePHP,WebService.

  • 通过CakePHP强大的Scaffolding脚手架功能,使得通过远程维护ViViPOS数据库变为可能,老板们可以在家中修改ViViPOS的商品价格,或统计销售信息.
  • 通过WebService接口,使得多台ViViPOS"协同作战"变为可能,例如可以在开机后自动访问总部的WebService进行数据下载,又例如A机打印纸用完后,自动通过WebService将需要打印的内容传输给离他最近的一台ViViPOS上的打印机进行打印,并提醒售货员

ViViPOS界面

ViViPOS给予XULRunner平台

什么是XULRunner? XULRunner是一种跨平台的应用开发程序框架,它使用JavaScript作为开发语言,XUL或HTML加上CSS作为构建UI的工具,使得Web开发人员运用现有的技术,快速构建功能强大的应用程序变为可能,著名的Firefox浏览器便是构建在这一平台上的.
Screen shot 2009-11-30 at 上午01.50.47

ViViPOS使用Javascript作为开发语言

可以毫不留情地说,JavaScript是Web2.0时代程序员的必会语言,没有之一.几乎每一个程序员或多或少都会对JavaScript有着丰富的认识,而使用JavaScript作为主要编程语言,使得ViViPOS的学习难度变得很低,可以说只要会进行网页编程的程序员,经过几天的培训后都能轻而易举的写出ViViPOS的扩展程序.
Screen shot 2009-12-03 at 下午09.05.10

ViViPOS的扩展性

既然ViViPOS和Firefox都是同宗同源,那么起强大的扩展能力是无庸置疑的.ViViPOS使用与Firefox完全一样的插件安装系统,使得企业在使用插件提供的功能时能享受到自动升级,自动兼容,自动整合的优势.
Screen shot 2009-12-03 at 下午09.02.42

24十一/090

使用MODx快速构建适合搜索引擎优化的CMS网站

MODx是一个轻量的,适合于SEO的CMS系统.MODx获得了<2009 Best Open Source PHP CMS>的提名,不过最终输给了功能更为强大,用户也更为广泛的Drupal.不过这不妨碍它作为轻量开源CMS的代表给希望快速制作网站的用户们提供一个更好地选择.

MODx的安装过程非常快速,几乎没有过多的页面跳转,安装过程便在ajax操作的提示下顺利完成,甚至测试数据库是否联通都是用ajax实现的,从安装程序的人性化可见MODx非常注重用户体验.

如果在安装过程中选择安装Sample Site,MODx便会自动将一个默认的网站导入当前的系统,方便第一次使用的用户理解系统.

MODx安装Sample site后显示的首页

而一个CMS是否强大和易用,通过其后台设置便可知道,让我们看一下MODx的后台界面

MODx后台界面

在后台界面中,操作员可以非常直观的对当前网站的栏位,文章以及互相之间的层次结构进行调整,而通过更加详细的功能设置则可以使MODx开启URL优化及更多的SEO优化功能.

后台设置之URL优化

如果你以为MODx的功能仅仅是这些那你就错了,MODx作为一个非常有潜力的CMS,当然少不了可自定义的扩展功能!在他的官方网站上,有着近600个扩展插件供你安装使用!

MODx的官方提供扩展下载

而最令人激动的是,MODx还有一个非常活跃的社区供所有使用MODx的用户交流讨论,至今为止已经有25万个发言了,当然如果你的英文不是很好的话,他也有使用中文交流的板块供你使用.

怎么样?下一个网站,使用MODx构建吧!

下载地址:
MODx 1.02.zip (3.6m)

安装需求:
PHP,MySQL数据库.

23十一/090

豪华汽车在婚庆用车市场中进行广告宣传的一种方法

婚庆用车需求在中国是一个非常火热的,但是新人在选择车辆选择性不大,往往只有如下两种选择:

  1. 听从婚庆公司的安排
  2. 通过亲朋好友之间关系借车,供婚庆当日使用,

上述两种方式的价格差距不大,一般20w左右的车(例如凯美瑞,雅阁)一天的租金是600元左右.按一次婚庆用车10量计算,则是6000元的花费.如果用车更多,级别更高,这个花费也会更多.根据商务部的《2006-2007年中国结婚市场发展调查报告》指出,我国城镇新人平均结婚花费约为12.66万元,而按照前文的用车费用估算,车辆花费占去了婚礼花费的4.7%.

而在中国,婚庆用车中有一个特殊的情况:即使婚车在巡游时有一些违反交通规则的行为,缺不会受到交警的处罚.

而我的想法则是:如果有一家豪华汽车公司,能够以适当的价格提供婚车服务,为新人解决上述问题,即可以做到在巡游的同时进行广告宣传,试想20辆相同颜色的某高级品牌的豪华轿车,一字长龙,视红绿灯而不顾,在路人的瞩目中穿过当地市中心,将会引起路人和其他苦苦等待红灯放行的车主多少的眼球!甚至有可能上当地的新闻!

而在婚宴时,也可在婚宴酒店的入口,放置该轿车品牌祝贺新人的易拉宝作为广告,婚宴时该品牌的轿车必然会成为婚宴时的热门话题.

分类: Idea 没有评论
22十一/090

搬家了

感谢owen的帮助,让我终于搬到了mt的主机上。

分类: IT 没有评论