【问题标题】:In MYSQL, how to summarise query results based on the parameters not specified in the query?在MYSQL中,如何根据查询中未指定的参数汇总查询结果?
【发布时间】:2012-11-17 03:29:20
【问题描述】:

我有一个包含大约 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 查询将花费大量时间。这是一个互联网应用程序,查询应在几秒钟内完成。

任何帮助将不胜感激。

【问题讨论】:

    标签: mysql summary


    【解决方案1】:

    您可以在一个查询中完成这两项操作

    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
    

    【讨论】:

      【解决方案2】:

      根据您的描述,我将有一个单独的聚合表来直接查询,其中包含您想要的那些“汇总”统计信息。 “人员”表添加/更改的频率。如果您只存储一个人的“年龄”,如果没有日期,年龄的基础是什么,并且您将来再次添加该人,他们将有多个记录......这样

      在 X 岁时,很多人已婚(或未婚)并接受过这种教育水平。 在 Y 岁时,有这么多人……等等。

      我会创建一个汇总表,类似于

      create table AgeStat ( 
         age int, 
         married int, 
         single int, 
         divorced int, 
         HighSchool int, 
         Associates int,
         Bachelors int,
         Masters int,
         Doctorate int )
      

      然后,向 person 表添加一个触发器,以便在插入(或根据需要包括更新/删除)期间,新记录仅将每个适用的计数加 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 )
      

      同样有一个触发器,可以根据每个年龄的两个组合元素更新计数。然后,如果您想要总“已婚”,您可以 sum(peoplecount) for age = 27 and maritalstat=(enumerator for "married" value)

      祝你好运,并希望它对您有所帮助。

      【讨论】:

      • DRapp,感谢您的解决方案。我在考虑你的建议,但是,我认为 Ebay、LinkedIn 等公司会使用其他机制。我已经修改了问题描述以显示有关我正在尝试做的事情的更多详细信息。考虑一下我是否必须在此表中添加 Location Country。没有。的列将非常大。此外,如果涉及关键字搜索,如何适应。你知道 Lucene 是否有我要找的东西吗?
      • @user1831240,我仍然会做预聚合表......你必须做数学。您跟踪多少个国家,多少婚姻状况,教育水平和年龄范围。甚至 100 年龄 * 4 婚姻(单身、已婚、离婚、丧偶)= 400,* 说 4 教育水平 = 1600,100 个国家 = 160,000 - 分布在 4+ 百万和不断增长的表中?现在,总年龄/婚姻总和()从 4 + mil 与 160,000 索引?您拨打电话。
      猜你喜欢
      • 2021-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-10
      • 1970-01-01
      • 1970-01-01
      • 2011-08-21
      • 1970-01-01
      相关资源
      最近更新 更多