Home  >  Article  >  Backend Development  >  请问一个关于PHP大数组去重的有关问题

请问一个关于PHP大数组去重的有关问题

WBOY
WBOYOriginal
2016-06-13 12:14:241013browse

请教一个关于PHP大数组去重的问题
请教一个问题,关于PHP大数组操作,一张表有几百万的数据要拿到PHP数组中做去重操作:
例如:id 性别 身份证三个字段,需要统计男女各有多少人(有其它特定逻辑,不能在MySQL中去重)
实现方法:id是自增的,每次按id取5w条数据,拿到一个数组中做去重操作
$count = array(
'男'  => array(
            '身份证1'  => 1,
    '身份证2'  => 1,
    ....
),
'女' => ...
);
最后看男女下共有多少个身份证即为去重后的数据
问题:随着数组越来越大,去重速度也越来越慢,不知道有没有其它解决方案或者优化方法,来请教一下,thx!
------解决思路----------------------
我们按你给出的数据做一个测试

drop table if exists play;<br /><br />CREATE TABLE `play` (<br />  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,<br />  `time` int(10) NOT NULL,<br />  `uid` int(10) unsigned NOT NULL,<br />  `game` varchar(255) NOT NULL,<br />  `channel` varchar(255) NOT NULL,<br />  `system` varchar(255) NOT NULL,<br />  `screen` varchar(255) NOT NULL,<br />  `network` varchar(255) NOT NULL,<br />  PRIMARY KEY (`id`),<br />  KEY `datetime` (`time`)<br />) charset=gbk;<br /><br />insert into play values<br />(1,1421812389,10000,'所有游戏-魔兽世界-0服','360-360联盟','WIN7','1024x768','电信'),<br />(2,1421812389,10001,'所有游戏-魔兽世界-1服','网易-网易联盟','XP','1366x768','联通'),<br />(3,1421812389,10000,'所有游戏-魔兽世界-0服','360-360联盟','WIN7','1024x768','电信');<br /><br />drop table if exists play_game;<br /><br />create table play_game ( game varchar(100) ) charset=gbk;<br /><br />insert into play_game values ('所有游戏'),('魔兽世界'),('0服'),('1服');<br /><br />drop table if exists play_channel;<br /><br />create table play_channel ( channel varchar(100) ) charset=gbk;<br /><br />insert into play_channel values ('360'),('360联盟'),('网易'),('网易联盟');<br /><br />select a.id, a.time, a.uid, b.game, c.channel, a.system, a.screen, a.network from play a, play_game b, play_channel c where <br />  find_in_set(b.game, replace(a.game, '-', ','))<br />  and<br />  find_in_set(c.channel, replace(a.channel, '-', ','))<br />
可得到这样的结果
<br />id time    uid  game   channel system screen  network <br />1  1421812389 10000 所有游戏 360   WIN7  1024x768 电信 <br />3  1421812389 10000 所有游戏 360   WIN7  1024x768 电信 <br />1  1421812389 10000 魔兽世界 360   WIN7  1024x768 电信 <br />3  1421812389 10000 魔兽世界 360   WIN7  1024x768 电信 <br />1  1421812389 10000 0服    360   WIN7  1024x768 电信 <br />3  1421812389 10000 0服    360   WIN7  1024x768 电信 <br />1  1421812389 10000 所有游戏 360联盟 WIN7  1024x768 电信 <br />3  1421812389 10000 所有游戏 360联盟 WIN7  1024x768 电信 <br />1  1421812389 10000 魔兽世界 360联盟 WIN7  1024x768 电信 <br />3  1421812389 10000 魔兽世界 360联盟 WIN7  1024x768 电信 <br />1  1421812389 10000 0服    360联盟 WIN7  1024x768 电信 <br />3  1421812389 10000 0服    360联盟 WIN7  1024x768 电信 <br />2  1421812389 10001 所有游戏 网易   XP   1366x768 联通 <br />2  1421812389 10001 魔兽世界 网易   XP   1366x768 联通 <br />2  1421812389 10001 1服    网易   XP   1366x768 联通 <br />2  1421812389 10001 所有游戏 网易联盟 XP   1366x768 联通 <br />2  1421812389 10001 魔兽世界 网易联盟 XP   1366x768 联通 <br />2  1421812389 10001 1服    网易联盟 XP   1366x768 联通 

再从这个结果出发,还有什么是不可用 SQL 做到的呢?

如果你永久性的将 所有游戏-魔兽世界-0服 改为 所有游戏,魔兽世界,0服 那就不需要在查询时执行 replace 函数了(当然这可能会涉及程序的改动),效率自然会有所提高
如果你再将最后的查询定义成视图的话,效率就又会提高不少(视图中如果一条记录的源数据没有被改变,则不做查询动作而直接返回缓存的结果)

------解决思路----------------------
怎么能把  所有游戏-wow-1服   存在一个字段里呢~
我是建议添加几个字段,将它拆开保存,然后在mysql上排重

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn