私は、MySQL 5.7.22、データベース内の2つのテーブルを持っている:postsとreasons。各投稿行には、多くの理由行があり、それに属しています。それぞれの理由には重みが関連付けられているため、各投稿には合計重みが関連付けられています。
重みの10ポイント(つまり、0、10、20、30など)の増分ごとに、その増分以下の合計重みを持つ投稿の数を取得します。その結果は次のようになるはずです。
 weight | post_count
--------+------------
      0 | 0
     10 | 5
     20 | 12
     30 | 18
    ... | ...
    280 | 20918
    290 | 21102
    ... | ...
   1250 | 118005
   1260 | 118039
   1270 | 118040
総重量はほぼ正規分布しており、非常に低い値と非常に高い値がいくつかありますが(最大値は現在1277)、大部分は中央にあります。の行数は120,000弱posts、約は120ですreasons。各投稿には、平均して5つまたは6つの理由があります。
テーブルの関連部分は次のようになります。
CREATE TABLE `posts` (
  id BIGINT PRIMARY KEY
);
CREATE TABLE `reasons` (
  id BIGINT PRIMARY KEY,
  weight INT(11) NOT NULL
);
CREATE TABLE `posts_reasons` (
  post_id BIGINT NOT NULL,
  reason_id BIGINT NOT NULL,
  CONSTRAINT fk_posts_reasons_posts (post_id) REFERENCES posts(id),
  CONSTRAINT fk_posts_reasons_reasons (reason_id) REFERENCES reasons(id)
);
これまでのところ、私は投稿IDと合計ウェイトをビューにドロップし、そのビューをそれ自体に結合して集計カウントを取得しようとしました。
CREATE VIEW `post_weights` AS (
    SELECT 
        posts.id,
        SUM(reasons.weight) AS reason_weight
    FROM posts
    INNER JOIN posts_reasons ON posts.id = posts_reasons.post_id
    INNER JOIN reasons ON posts_reasons.reason_id = reasons.id
    GROUP BY posts.id
);
SELECT
    FLOOR(p1.reason_weight / 10) AS weight,
    COUNT(DISTINCT p2.id) AS cumulative
FROM post_weights AS p1
INNER JOIN post_weights AS p2 ON FLOOR(p2.reason_weight / 10) <= FLOOR(p1.reason_weight / 10)
GROUP BY FLOOR(p1.reason_weight / 10)
ORDER BY FLOOR(p1.reason_weight / 10) ASC;
ただし、これは非常に遅く、15分間は終了せずに実行しましたが、本番環境ではできません。
これを行うより効率的な方法はありますか?
データセット全体のテストに関心がある場合は、こちらからダウンロードできます。ファイルは約60MBで、約250MBに拡張されます。または、GitHub要旨には12,000行あります。
w.weight-それは正しいですか?合計重み(関連する理由行の重みの合計)がlteの投稿をカウントしようとしていw.weightます。