我有一个大约有400万行的MySQL表。我们说这个表如下:
表Person
中的列:
Id
Name
Age
Marital Status
Education Level
当我根据Age
运行查询时,我还希望得到不同婚姻状况,同时具有不同“教育程度”和“位置国家”的年龄相同的人的摘要计数。
当我根据年龄和教育水平运行查询时,我还希望得到具有不同婚姻状况的相同年龄和教育程度以及不同“位置国家”的人的摘要计数。
例如,发出的查询将是SELECT * FROM Person WHERE Age = 27;
。我还想要SELECT Education Level, COUNT(*) FROM Person WHERE Age = 27 GROUP BY Education Level;
和SELECT Location Country, COUNT(*) FROM Person WHERE Age = 27 GROUP BY Location Country;
此外,当我必须根据描述中的关键字进行搜索并希望对每个其他列进行汇总计数时,这对我来说变得更具挑战性。我正在开发的应用程序是一种搜索引擎。这可以在像Ebay这样的网站上看到,
我可以单独运行这些查询。但是,有400万行,GROUP BY查询将花费大量时间。这是一个互联网应用程序,查询应该在几秒钟内完成。
非常感谢任何帮助。
答案 0 :(得分:0)
您可以在一个查询中同时执行这两项操作
SELECT p.*, count(p2.id)
FROM Person p, Person p2
WHERE p2.Age = p.age and p2.marital != p.marital and p1.education != p2.education
GROUP BY p1.id
在这种情况下,我建议将数据保存在memcache
缓存中。如果新数据插入到表中或在一些过期时间之后,您可以使缓存过期,以避免长查询执行。另一个改进是使用LIMIT来减少DB返回的行数,如下所示:
SELECT p.*, count(p2.id)
FROM Person p, Person p2
WHERE p2.Age = p.age and p2.marital != p.marital and p1.education != p2.education
GROUP BY p1.id
LIMIT 10
答案 1 :(得分:0)
根据您的描述,我将有一个单独的聚合表来直接查询,具有您想要的那些“汇总”统计数据。 “人员”表被添加/更改的频率如何。如果你只存储一个人的“年龄”,如果没有日期,年龄的基础是什么,而你将来再添加一个人就会有多个记录...这样
在X岁时,有很多人结婚(或没有),并接受过这种教育。 在Y岁,这么多人......等等。
我会创建一个摘要表,比如
create table AgeStat (
age int,
married int,
single int,
divorced int,
HighSchool int,
Associates int,
Bachelors int,
Masters int,
Doctorate int )
然后,在人员表中添加一个触发器,以便在插入期间(或根据需要包括更新/删除),新记录只会为每个相应的计数增加1。
然后,对于您的网络应用,可以立即从这个年龄= 27的汇总表中获取一条记录,并且您拥有所有分类统计数据。
但是,如果您明确想知道有多少与硕士学位结婚,您将不得不回到主人名单。
或者,您可以执行类似的预聚合,但需要降低像
这样的粒度级别create table AgeStat (
age int,
maritalstat int, -- but I would actually use an enumerated value for marital status
educationlevel int, -- and education level vs a hard description of each.
peoplecount int )
同样有一个触发器,根据每个年龄的两个组合元素更新计数。然后,如果你想要总“已婚”,你可以总结(人数)年龄= 27和maritalstat =(调查员为“已婚”价值)
祝你好运,并希望它能为你提供替代解决方案。