mysql - 优化 MySQL GROUP BY/ORDER BY 计算集合交集

标签 mysql sql performance optimization group-by

为了使问题更清楚,此场景有所简化。 我的情况涉及MySQL中的一组数据记录。

CREATE TABLE `records` (                                          
  `id` bigint(20) NOT NULL,                                                       
  `property1` bigint(20) NOT NULL,
  `property2` bigint(20) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `property1` (`property1`),
  KEY `property2` (`property2`)
);

从每条记录中,我们根据记录数据生成并存储可变数量的键(散列)。

CREATE TABLE `rkeys` (
  `rKey` bigint(20) NOT NULL,
  `rId` bigint(20) NOT NULL,
  KEY `rKey` (`rKey`),
  KEY `rId` (`rId`),
  FOREIGN KEY (`rId`) REFERENCES `records` (`id`)
);

(键值是散列,可以更均匀地分布在键空间中。)

例如,可能有 500 万条记录和 5000 万个键。

我试图做的是对键集进行模糊搜索——将一条记录与数据库中具有最多共同键的记录进行匹配。还需要根据记录表中的属性过滤结果。

我一直在使用的查询如下所示:

SELECT rkeys.rId, records.property1, SUM(1) as score 
FROM rkeys, records
WHERE 
   (rKey = 10 OR rKey = 11 OR rKey = 13 OR rKey = 14) AND 
    rkeys.rId = records.id AND 
    records.property1 = 1 AND
    records.property2 = 2 
GROUP BY rId ORDER BY score DESC;

如果具有任何给定键的记录数相当小,则性能还可以;问题是如果我点击了一个出现在几千条记录中的键(比如 5000 条)。突然之间,GROUP BY/ORDER BY 的性能跌落悬崖(每次查询 15-20 秒)。请注意,平滑 key 分布并不是真正的选择——记录数据本身分布不均匀。

针对记录的连接问题似乎并不是问题的核心——我只是将其包括在内以供引用。如果我只想这样做,我仍然会遇到同样的问题:

SELECT rId, SUM(1) as score 
FROM rkeys
WHERE rKey = 10 OR rKey = 11 OR rKey = 13 OR rKey = 14
GROUP BY rId ORDER BY score DESC;

解释输出:

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: rkeys
         type: index
possible_keys: rKey
          key: rKey
      key_len: 8
          ref: NULL
         rows: 1
        Extra: Using where; Using temporary; Using filesort

有没有一种方法可以重构此表或查询以加快此操作?

最佳答案

您是否尝试过向这些字段添加非聚集索引(indexes)?我过去没有看到 Keys 自动执行此操作,除了在某些 SQL 引擎中主键声明执行的一些隐式聚簇索引创建之外。

关于mysql - 优化 MySQL GROUP BY/ORDER BY 计算集合交集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4673396/

相关文章:

mysql - 如何从单列创建两列输出

php - 当我尝试从 MySQL 检索信息时,我的页面崩溃了

Javascript 检查除零之外的错误陈述的最佳方式

带日期的MySQL查询

MySQL Slow join - 但并非总是如此,也不是在所有表上

algorithm - Find Top 10 Most Frequent visited URl,数据跨网络存储

mysql - 错误 : Handshake inactivity timeout in Node. js v6.9.1 和 MySQL

php - 如何将数组分隔成变量

mysql - 我是否应该合并两个具有相同列但每个表都与不同表有关系的表?

asp.net - 将整个数据集传递给 MSSQL 2005 中的存储过程