我很难优化像
这样的查询SELECT RESULT_ID FROM RESULTS
WHERE SOURCE = 1 AND GROUP=2 AND SCORE1 BETWEEN 20 AND 100
ORDER BY SCORE2 LIMIT 450;
在4000万行innodb表上。该查询可能需要排序多达1500万个结果才能获得前450名。到目前为止,我已尝试过:
此外,是否有任何可以优化这类查询的OLAP多维数据集实现?
答案 0 :(得分:1)
我建议创建一个包含这450行的单独表,并在每次插入新行或更新旧行时计算,并参考另一个表。
这样您的查询就不需要每次都浏览所有行。
答案 1 :(得分:1)
您可以预先指定通用分数范围。例如,您可以创建几种类型的范围:
1 2 3 4
RANGE_50 = { 0..50, 51..100, 101..150, 151..200 }
RANGE_100 = { 0..100, 101..200 }
RANGE_200 = { 0..200 }
这些范围类型可以在表格中创建为列,并且必须根据 score1 的值进行更新。
然后你就可以使用这样的查询:
SELECT RESULT_ID FROM RESULTS
WHERE SOURCE = 1 AND GROUP=2 AND RANGE_100 = 2
ORDER BY SCORE2 LIMIT 450;
答案 2 :(得分:0)
你正在寻找的东西,恕我直言,是一种在(理论上)无限流的项目中获得前K项的方法。
我不会尝试直接在mysql中解决这个问题,因为您的输入是流而不是固定数据集。此外,考虑到数据集大小,在每个插入上从头开始重新计算顶部K是不可能的。
我要做的是在新项目进入时更新顶部K的紧凑表示。对于每个元素,取其得分,并保留到目前为止看到的顶部K元素的堆。
更正式一点:给定数据流q1 ,. 。 。 ,qn,如果Score(qj)大于堆中的最小分数,则将qj添加到堆中。在这种情况下,应该从堆中逐出最小的估计分数。
您有多个分数列,用户可以使用范围查询向前450名询问任何列组合。
从概念上讲,我会做的是:
希望它有所帮助。