大家好
我现在有个需求,就是有个论坛。
论坛要统计各个地区看各种帖子的人数
我现在有一个表,表结构
ID 主键
region 区域
contrey 国家
lang 语言
count 读取的人数
现在我要统计在这个区域下某个区域某个语言的所有人数
我的sql文是
select sum(*) from tablename where region = 6 and contrey = "cn" and lang in ("111111","22222","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333")在in中的元素是不定的,是从页面中选出来的最多的时候是3500多个
数据库中这个表有8w条数据现在用上面的方法(in)很慢,应该在10秒左右,接受不了啊
还希望大家帮忙啊。
对了我用的是mysql
我现在有个需求,就是有个论坛。
论坛要统计各个地区看各种帖子的人数
我现在有一个表,表结构
ID 主键
region 区域
contrey 国家
lang 语言
count 读取的人数
现在我要统计在这个区域下某个区域某个语言的所有人数
我的sql文是
select sum(*) from tablename where region = 6 and contrey = "cn" and lang in ("111111","22222","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333","33333")在in中的元素是不定的,是从页面中选出来的最多的时候是3500多个
数据库中这个表有8w条数据现在用上面的方法(in)很慢,应该在10秒左右,接受不了啊
还希望大家帮忙啊。
对了我用的是mysql
解决方案 »
- mysql中的auto_increment怎么重新排序
- Lost connection to MySQL server at 'reading initial communication packet', syste
- 从mysql 中取出 最后十条 msg = 101 的记录
- mysql触发器问题
- Lost connection to MySQL
- 帮小弟看个A表数据导入B表的问题
- mysql外连接问题
- MYSQL 怎样 从远端服务器备份数据 到本地机??
- sql:随机百分比取记录,求指教~
- 如何在vc6.0使用mysql,就是怎么在c语言中使用
- myphpadmin怎么安装 呢?
- MYSQL,如何OPTIMIZE TABLE几十GB以上的大表?
region、contrey字段有多少种值?如果多,可以建立
lang、region、contrey复合索引
因为从表的结构来看,region 区域、contrey 国家、lang 语言三列肯定是大量的重复,我估计都不会超过50个种类。那从索引的原理看,这都是属于不适合建索引的列。建联合索引可能会好点。楼主表中:count 读取的人数,这一列是什么意思啊?你说“在in中的元素是不定的,是从页面中选出来的最多的时候是3500多个”,这3500多个都是不同的值吗?这点比较关键。不过我看你给的例子,很多雷同啊。
2) 优化一下这个in后的数据,太多重复的 "33333" 不如 in ("111111","22222","33333")效率高。
真是太感激了,对不起我的问题可能没有问好
1。count 读取的人数,这一列是什么意思啊?
count数是这个帖子被多少个人读取过。
因为业务需要我要分析每个帖子被多少个人读取过。并且还要搜集每个国家有多少个人看过这个帖子。
2。在in中的元素是不定的,是从页面中选出来的最多的时候是3500多个”,这3500多个都是不同的值吗?这点比较关键。不过我看你给的例子,很多雷同啊。
对不起我写的不对应该是:
select sum(*) from tablename where region = 6 and contrey = "cn" and lang in ("111111","22222","33333","44444","55555","66666","77777","88888")
蓝色的部分最多的时候是3500多个。
3。我现在的表中lang、region、contrey就是复合索引,也很慢阿。
还希望大家多多帮忙啊
show index from tablename ;
explain sql语句
贴结果
2,sum(*) 应该改为sum(count)吧。
3,就8W条数据,10s的查询有点离谱啊。应该放弃联合索引rcl(region,country,language),而选用rc(region,country),当使用rcl时in的结果只能增加IO,还不如根据rc得到所有语言的记录,然后在程序端进行累加。
4,languge这个字段如果用字符串存储有点浪费空间,建议采用int存储,这样建立索引时会省不少空间的,语言的种类应该是少数吧。
5,如果在应用中确实需要统计这样的实时性数据,建议采用ajax+memcached来减少服务器的压力。
CREATE TABLE `etagtest` (
`ETAGADVERID` int(32) NOT NULL AUTO_INCREMENT,
`REGION` varchar(15) DEFAULT NULL,
`CONTREY` varchar(100) DEFAULT NULL,
`LANG` varchar(50) DEFAULT NULL,
`COUNT` int(32) DEFAULT NULL,
`UPDATEID` int(32) DEFAULT NULL,
`UPDATEDATE` date DEFAULT NULL,
PRIMARY KEY (`ETAGADVERID`),
KEY `fk_RETAGADVER` (`REGION`,`CONTREY`,`LANG`)
) ENGINE=InnoDB AUTO_INCREMENT=16670 DEFAULT CHARSET=utf8;执行语句:
select sum(`COUNT`) from etagtest where LANG in ('00000001','00000002','00000003','00000004',...,'00003099','00003100')
内容太长了,我贴不全就省略了一些部分。+----+-------------+------------+------+---------------+------+---------+------+
-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref |
rows | Extra |
+----+-------------+------------+------+---------------+------+---------+------+
-------+-------------+
| 1 | SIMPLE | retagadver | ALL | NULL | NULL | NULL | NULL |
84490 | Using where |
+----+-------------+------------+------+---------------+------+---------+------+
-------+-------------+
1 row in set (0.07 sec)现在速度已经可以了,原因就是我把原来的表索引改称复合索引了但是是这样的:
我现在没秒100左右的请求,感觉现在的SQL文还是挺慢的,
SELECT--IN这种检索方式不是比较慢吗,
各位高手能不能帮帮忙把这个SQL文再优化一下吗?
想想办法
这些数据是怎么来的呢,如果是表中,直接用 and exists(select 1 from t where conditon) 对条件字段建立索引
如果是其他方式得来的,增加一个表结构维护这些信息也是可以的。
这些数据是怎么来的呢?
这些数据是从页面中传过来的,本来我也想用exists的但是从页面传过来的都是数值
所以就放弃了exists
可以创建索引的,在3列上创建复合索引,顺序是region ,contrey , lang ,这样他们的唯一性还是很高的,并且只需要维护一个索引,只要前面2个是const 就能利用到此索引,