Submitted by gouki on 2013, March 21, 11:40 AM
在mysql里面,我们偶尔会有这样的sql出现:
select userid,count(userid) as cnt from xxxxxtable group by userid;
这样的sql在mongo里怎么实现呢?其实也相对比较简单
PHP代码
- <?php
- $mongo = new Mongo();
- $mongo->selectDB('xxx');
- $collection = $mongo->selectCollection('表');
-
- $field = array('userid'=>1);
- $cnt = array('cnt'=>0);
- $result = $collection->group($field,$cnt,"function(obj,pref){pref.cnt++;}");
打印出来的结果也很方便识别:
XML/HTML代码
- Array
- (
- [retval] => Array
- (
- [0] => Array
- (
- [userid] => 11111
- [cnt] => 2
- )
- //省略
- )
-
- [count] => 21
- [keys] => 11
- [ok] => 1
- )
果然轻轻松松啊
Tags: mongo, mysql
DataBase | 评论:0
| 阅读:21849
Submitted by gouki on 2013, February 8, 12:06 PM
看到这个的时候,觉得不是特别爽:/usr/local/mysql/bin/mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory
然后很纠结,于是想办法解决,其实很容易;
On Debian, if you get the error:
/usr/local/mysql/bin/mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory
type the following
apt-get install libaio1 libaio-dev
On Redhat/Fedora/CentOS:
yum install libaio
DataBase | 评论:0
| 阅读:22050
Submitted by gouki on 2013, February 5, 12:15 AM
在使用redis的时候,出现了Error: read error on connection.
找了一下相关资料,在官方也有很多人提出这个问题
phpredis的作者的意思是,是因为default_socket_timeout的问题,将它设为0就好了.
但很多人都说设为0,在60秒后还是会挂 ,只有设为-1才OK
于是,在命令行下subscribe的时候,先init_set('default_socket_timeout',-1);
问题解决 .
Tags: redis
DataBase | 评论:0
| 阅读:23552
Submitted by gouki on 2012, December 28, 9:44 AM
这是昨天SAE分享的一篇文章,开始的时候,我看了一遍,发现好象没有什么特别的内容,但再仔细看的时候,发现居然可以这样做。。。
问题描述:
我们要访问的表是一个非常大的表,四千万条记录,id是主键,program_id上建了索引。
执行一条SQL:
select * from program_access_log where program_id between 1 and 4000
这条SQL非常慢。我们原以为处理记录太多的原因,所以加了id限制,一次只读五十万条记录
select * from program_access_log where id between 1 and 500000 and program_id between 1 and 4000
但是这条SQL仍然很慢,速度比上面一条几乎没有提升。Mysql处理50万条记录的表,条件字段还建了索引,这条语句应该是瞬间完成的。
问题分析:
这张表大约容量30G,数据库服务器内存16G,无法一次载入。就是这个造成了问题。
这条SQL有两个条件,ID一到五十万和Program_id一到四千,因为program_id范围小得多,mysql选择它做为主要索引。
先通过索引文件找出了所有program_id在1到4000范围里所有的id,这个过程非常快。
接下来要通过这些id找出表里的记录,由于这些id是离散的,所以mysql对这个表的访问不是顺序读取。
而这个表又非常大,无法一次装入内存,所以每访问一条记录mysql都要重新在磁盘上定位并把附近的记录都载入内存,大量的IO操作导致了速度的下降。
问题解决方案:
1. 以program_id为条件对表进行分区
2. 分表处理,每张表的大小不超过内存的大小
然而,服务器用的是mysql5.0,不支持分区,而且这个表是公共表,无法在不影响其它项目的条件下修改表的结构。所以我们采取了第三种办法:
select * from program_access_log where id between 1 and 500000 and program_id between 1 and 15000000
现在program_id的范围远大于id的范围,id被当做主要索引进行查找,由于id是主键,所以查找的是连续50万条记录,速度和访问一个50万条记录的表基本一样
总结:
这是一个在千万笔记录表中由于使用了索引导致了数据查找变慢的问题,有一定的典型性和大家交流下!
-----------
看我标红的那一段,原来还能够这样做,以前真的没有注意过,也从来没有想过,先利用主键做一次过滤。这样效率会好很多啊
上述内容来自:http://ourmysql.com/archives/108?f=wb,该网站还有很多技巧值得一看。
Tags: sae, mysql, 索引
DataBase | 评论:2
| 阅读:17093
Submitted by akuma on 2012, November 30, 2:15 PM
转来的文章,主要是mysql我熟,其他我不知道。。。。
文章来自:http://www.zhixing123.cn/net/sql-random-read-records.html
以下是全文:
利用一条SQL语句从数据库Table表中随机获取N条记录,各数据库的SQL语句略有不同,如下:
1、MySql
Select * From TABLE Order By Rand() Limit N
以上代码效率不高,自己对1000条数据表随机取10条的测试结果为耗时0.125s,有网友推荐改为以下代码效率有大幅提高,耗时为 0.005s,不过结果是随机从某个位置开始取N条记录,而不是随机取N条记录,略有差异。详细说明见mysql使用rand随机查询记录效率测试。
SELECT * FROM `TABLE` a join (SELECT ROUND(RAND() * ((SELECT MAX(id) FROM `TABLE`)-(SELECT MIN(id) FROM `TABLE`))+(SELECT MIN(id) FROM `TABLE`)) AS id) AS b WHERE a.id >= b.id ORDER BY a.id LIMIT N;
2、SQL Server
Select TOP N * From TABLE Order By NewID()
NewID()函数将创建一个 uniqueidentifier 类型的唯一值。
3、Access
Select TOP N * From TABLE Order By Rnd(ID)
Rnd(ID) 其中的ID是自动编号字段,可以利用其他任何数值来完成,比如用姓名字段(UserName)
Select TOP N * From TABLE Order BY Rnd(Len(UserName))
4、Oracle
1)dbms_random包
1 select * from (select * from Table order by dbms_random.value) where rownum < N;
注:dbms_random包需要手工安装,位于$ORACLE_HOME/rdbms/admin/dbmsrand.sql
1 dbms_random.value(100,200)
可以产生100到200范围的随机数
2)按概率抽取:
select * from Table sample(百分比);
例:
select * from Table sample(10);
取表Table中记录条数的10%条记录
3)sys_guid
select * from (select * from Table orderby sys_guid()) where rownum<N;
5、postgreSQL
select * from Table order by random() limit N
DataBase | 评论:0
| 阅读:16952