私は、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
ます。