ฉันมีสองตารางในฐานข้อมูล MySQL 5.7.22: และ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
และรอบ reasons
120 แต่ละโพสต์มีเหตุผลโดยเฉลี่ย 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 อีกวิธีหนึ่งที่มี 12,000 แถวในส่วนสำคัญ GitHub ที่นี่
w.weight
- ใช่ไหม? ฉันกำลังมองหาที่จะนับโพสต์ด้วยรวมน้ำหนัก (ผลรวมของน้ำหนักของแถวเหตุผลที่เกี่ยวข้อง) ของw.weight
LTE