mySQL查询分组记录的前N个条目

标签 mysql greatest-n-per-group

我是 MySql 和一般数据库的新手。我有一个查询,它是我通过在线资源的片段以及跟踪和错误一起构建的。它真的很慢(27 秒),我认为它可以优化。也许有人可以帮我解决这个问题。

这是我的 mySQL - 数据库的数据结构。版本 5.1.51-0

|- purchaseID -|- customerID -|- emotionID -|- customerCountryCode -|- customerContinentCode-|
|     1        |     2345     |     0       |        US             |            NA          |
|     2        |     2345     |     3       |        US             |            NA          |
|     3        |     4456     |     0       |        UK             |            EU          |
|     3        |     4456     |     5       |        UK             |            EU          |
|     4        |     4456     |     2       |        UK             |            EU          |
|     5        |     4456     |     2       |        UK             |            EU          |
|     6        |     1234     |     0       |        US             |            NA          |
|     7        |     6678     |     0       |        US             |            NA          |
|     8        |     9900     |     0       |        US             |            NA          |
|     9        |     3334     |     0       |        US             |            NA          |    
|     10       |     3334     |     4       |        US             |            NA          |

数据库用于保存所有已购买的商品。对于每次购买,customerID、他来自的国家和大陆都会被保存。客户还可以根据一组 6 种情绪来评价他的购买。 (高兴,失望,...)他选择的情绪被保存为emotionID

所以现在我需要一个查询来为我获取特定 emotionID 的前 6 位客户以及百分比信息。假设我寻找 emotionID = 0 这是我想要得到的:

|- customerID -|- emotionPercent -|
|     1234     |        100       |     
|     6678     |        100       |     
|     9900     |        100       | 
|     2345     |        50        |     
|     3334     |        50        | 
|     4456     |        25        |    

我正在使用这个查询:

SELECT customers.customerID, Count( customers.emotionID ) / C.totalPeople * 100.0 AS emotionPercent 
FROM `customers` 
INNER JOIN 

    (SELECT customers.customerID, Count( customers.emotionID ) AS totalPeople
    FROM `customers` 
    GROUP BY customerID) C 

ON customers.customerID = C.customerID 
WHERE customers.emotionID = 0 
GROUP BY customers.customerID 
ORDER BY emotionPercent DESC 
LIMIT 0,6

我已经搜索了答案,但额外的百分比计算让我失望了。我找到了一些解决方案,需要填充某种临时表,但我无法让它工作。

问题是: 现在,数据库中有 140,000 个条目,此查询大约需要 27 秒。这是对的吗?使用 SQL - Server 会显着提高速度吗?

我不明白的是:询问世界上最幸福的国家快如闪电(0.4 秒),但在结构上与第一个查询(27 秒)相似:

SELECT customers.customerCountryCode, Count( customers.emotionID ) / C.totalPeople * 100.0 AS emotionPercent 
FROM `customers` 
INNER JOIN 

    (SELECT customers.customerCountryCode, Count( customers.emotionID ) AS totalPeople
    FROM `customers` 
    GROUP BY customerCountryCode) C 

ON customers.customerCountryCode = C.customerCountryCode 
WHERE customers.emotionID = 0 
GROUP BY customers.customerCountryCode 
ORDER BY emotionPercent DESC 
LIMIT 0,6

当我将此示例中的 INNER QueryGROUP BY 更改为 customerID 时,查询也会一直持续下去。因此,导致问题的是按 customerID 的分组。但是为什么?

customerCountryCode 定义为 varchar(2)customerID 是一个 int(11)。这会导致查询性能的巨大差异吗?有没有更合适的变量类型? customerID 最多可以有 8 个数字。

很多问题!感谢阅读和任何帮助!

最佳答案

首先,如果您认为数据库中的条目会膨胀,或者如果您的条目很高而服务器却很慢,恕我直言,您可能希望预处理数据并将其存储到另一个数据库中汇总结果,这样,您就不必一遍又一遍地请求相同的过程。另外,尝试为您的应用程序使用缓存插件。用于 php 的内存缓存或 j2ee 上的 ehcache 将是安全的选择。

关于mySQL查询分组记录的前N个条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4418146/

相关文章:

php - 在复选框中显示mysql数据

mysql - 按所有枚举值分组而不指定枚举值

sql - 在 PostgreSQL 中使用 group by 时如何获取最后一条记录

mysql - 使用多个表的 SQL SELECT

php - 如何在单个 php 准备语句上同时使用 SELECT 和 INSERT 查询?

MySQL获取每个产品组具有最小列值的行

mysql - 查询每个距离的最佳时间

mysql - 如何在 MySQL 和 Rails 中使用 SELECT DISTINCT ON

mysql - 考虑两个表的联接,获取重复行的最大值

mysql - 将excel中更新的详细信息上传到mysql数据库