求高手的一个解决方案!
现在我手里有竟将20W的会员数据,因为很多会员都留有留的有QQ ! 因为腾讯已经给出了验证QQ是否在线的客服代码! 我现在想很快的区分开那些会员在线状态!本来想先判断会员是否在线状态,更新数据库后在放入条件查询,但是20w的数据更新状态太耗时了!
求大神们给个解决方案! --------------------编程问答-------------------- 没说清楚更新的策略。数据库刷20万的数据还是很快的。 --------------------编程问答-------------------- 目标很明确,更具会员的QQ信息,筛选查询实时在线的会员里列表! --------------------编程问答--------------------
由于每一个会员是否在线的状态都要通过在线客户的代码验证,所以我刚开始的思路需要更新到每一条数据!
这样效率值得怀疑!
--------------------编程问答-------------------- 逐条判断肯定是要的了
更新的时候 采用事务提交
可以每500条或更多在线状态的数据
commit一次 --------------------编程问答--------------------
楼上的意思是,展示数据列表之前,先吧会员的数据遍历一次,修改当前QQ的在线状态! 然后再更具条件条件查询? --------------------编程问答--------------------
只是在展示数据时 将会员qq是否在线状态显示?
这样 qq是有用脚本判断是否在线的方式
--------------------编程问答-------------------- QQ系在客户代码,src返回的是不同图片!src="http://wpa.qq.com/pa?p=1:<%# Eval("QQ") %>:4" --------------------编程问答-------------------- 那又怎么样呢? 你难道用别的就不用去便利20W的数据量了? 效率高 存储过程呗 骚年 --------------------编程问答-------------------- 可以批量的处理。比如5000条5000条的。记得带事务哦。 --------------------编程问答-------------------- 前几天在论坛上看到一个可以用存储过程调用webservice的,我觉得你可以一试。利用webservice可以判断是否在线,这很容易做到,再配合存储过程的调用,再加上事务的处理。应该不难。 --------------------编程问答--------------------
现在我手里有竟将20W的会员数据,因为很多会员都留有留的有QQ ! 因为腾讯已经给出了验证QQ是否在线的客服代码! 我现在想很快的区分开那些会员在线状态!
本来想先判断会员是否在线状态,更新数据库后在放入条件查询,但是20w的数据更新状态太耗时了!
求大神们给个解决方案!
仅凭你的这个“空想出来”的需求,我看不到它的意义。假设说腾讯api给出的状态可以反映最近30秒钟内的情况,那么你是打算每隔30秒钟轮询一遍20W人的状态么?如果不轮询,你又怎么知道30秒钟之后哪些人的状态改变了呢?
有些人满脑筋只有数据库表“增删改查”,没有协同服务的设计概念。
如果你是做一个实用的交互操作软件,那么需要显示用户在线状态时才会调用一下api。有什么必要保存到数据库里?凭空出来的“设计流程”,其白白浪费的时间是可怕的。 --------------------编程问答--------------------
目标很明确,更具会员的QQ信息,筛选查询实时在线的会员里列表!
应该结合实际去指定目标。你需要稍微深入一点才能搞清楚流程设计(又没有速度和价值保证)的时候,一定不要停留在标题党方式的设计上。 --------------------编程问答-------------------- 才能搞清楚流程设计(又没有速度和价值保证)的时候 --> 才能搞清楚流程设计(有没有速度和价值保证)的时候
所以许多设计,首先需要你实际调查研究数据的来源和使用流程。而绝不是拿着静态的数据库表就空想自己的操作。 --------------------编程问答-------------------- 数据库无论是查询、插入、更新20万条数据都几乎不耗时,耗时的部分主要在查询那个qq在线状态。我用的是http://webpresence.qq.com/getonline?Type=1&这个页面,每次可以同时查询5个QQ号码。使用.net4.0的TPL并行运算的话20万条数据约莫要20分钟左右。
当然了,如果你能直接查询腾讯的数据库的话,一次取20万条数据依然会很快。
问题出在每次最多取5个,我试了下,一般一次连接检查5个QQ的状态的话约莫要0.065秒,20万条数据要4万次连接至少要43分钟才行。
所以我有以下几个建议:
1、QQ状态不需要存入数据库。这是因为在线状态都是实时更新的,即使存入数据库,你要取出来还是要连接腾讯网络判断下,实在没什么必要。当然了,数据库根本不算是个问题,20万条数据无论如何增删改也不会占去20-40分钟。
2、不提供显示当前在线总人数的查询控件。虽然我不知道你的UI是什么样子的,但是无论是谁都不会一眼去看20万个QQ的在线状态。唯一有关的可能就是会有一个控件显示当前在线的总人数,由于更新时间过长,建议此功能取消。
3、分页显示在线QQ号码,每次只显示一部分。或者也可以让用户选择将某些重要的QQ号码加入优先级,每次优先读取这些号码的在线状态。也可以选定号码的查询范围,总之尽可能地使每次查询的时间缩短在2秒内,2/0.065大约为30条数据。
下面我贴一下我写的测试用代码,如果你有什么问题的话敬请联系。
--------------------编程问答-------------------- 学习。。。。。
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace QqStatusQuery
{
internal class Program
{
private static Dictionary<int, bool> dictionary = new Dictionary<int, bool>();
private const char colon = ':';
private static int idCount;
public static void Main(string[] args)
{
Console.WriteLine("QQ状态检查程序");
for (int i = 200000; i < 400000; i++)
{
dictionary.Add(i, false);
}
Console.WriteLine("数据读取完毕");
var list = new List<QqId>() { new QqId() };
int count = 0;
foreach (var id in dictionary.Keys)
{
if (!list[count].IsFull)
{
list[count].Add(id);
}
else
{
list.Add(new QqId());
count++;
}
}
Console.WriteLine("开始检查状态");
var startTime = DateTime.Now;
idCount = list.Count;
Parallel.ForEach<QqId>(list, id => CheckStatus(id));
Console.WriteLine("一共耗时" + (DateTime.Now - startTime).TotalSeconds.ToString());
//Console.WriteLine("以下为登录状态");
//foreach (var key in dictionary.Keys)
//{
// if (dictionary[key])
// {
// Console.WriteLine(key);
// }
//}
Console.Read();
}
private static void CheckStatus(QqId id)
{
var html = GetWebResponse(BuildString(@"http://webpresence.qq.com/getonline?Type=1&", id[0], colon, id[1], colon, id[2], colon, id[3], colon, id[4], colon));
var splitedString = html.Split(';');
for (int i = 0; i < splitedString.Length; i++)
{
var status = splitedString[i];
if (!string.IsNullOrEmpty(status) && status[status.Length - 1] == '1')
{
dictionary[id[i]] = true;
}
}
}
private static string GetWebResponse(string url)
{
string html = string.Empty;
try
{
var request = WebRequest.Create(url);
var response = request.GetResponse();
var stream = response.GetResponseStream();
var encoding = Encoding.GetEncoding("GBK");
var reader = new StreamReader(stream, encoding);
var readbuffer = new char[short.MaxValue];
var n = reader.Read(readbuffer, 0, short.MaxValue);
while (n > 0)
{
html = BuildString(html, new string(readbuffer, 0, n));
n = reader.Read(readbuffer, 0, short.MaxValue);
}
}
catch (WebException)
{
}
return html;
}
private static string BuildString(params object[] inputStrings)
{
var builder = new StringBuilder();
foreach (var inputString in inputStrings)
{
if (inputString != null)
{
builder.Append(inputString.ToString());
}
}
return builder.ToString();
}
}
internal class QqId
{
private int[] Ids;
private byte count;
internal QqId()
{
Ids = new int[5];
}
internal int this[int index]
{
get
{
return Ids[index];
}
}
internal bool IsFull
{
get
{
return count == 5;
}
}
internal void Add(int id)
{
Ids[count++] = id;
}
}
}
补充:.NET技术 , ASP.NET