我是SQL新手,需要帮助。我有4个表:
helmet arm
+------+---------+-----+--------+ +------+---------+-----+--------+
| id | name | def | weight | | id | name | def | weight |
+------+---------+-----+--------+ +------+---------+-----+--------+
| 1 | head1 | 5 | 2.2 | | 1 | arm1 | 4 | 2.7 |
| 2 | head2 | 6 | 2.9 | | 2 | arm2 | 5 | 3.1 |
| 3 | head3 | 7 | 3.5 | | 3 | arm3 | 2 | 1.8 |
+------+---------+-----+--------+ +------+---------+-----+--------+
body leg
+------+---------+-----+--------+ +------+---------+-----+--------+
| id | name | def | weight | | id | name | def | weight |
+------+---------+-----+--------+ +------+---------+-----+--------+
| 1 | body1 | 10 | 5.5 | | 1 | leg1 | 8 | 3.5 |
| 2 | body2 | 5 | 2.4 | | 2 | leg2 | 5 | 2.0 |
| 3 | body3 | 17 | 6.9 | | 3 | leg3 | 8 | 1.8 |
+------+---------+-----+--------+ +------+---------+-----+--------+`
我希望找到总重量小于等于输入值的最高 totaldef
例如:totalweight <= 10
查询:
select
helmet.name as hname, body.name as bname,
arm.name as aname, leg.name as lname,
helmet.poise + body.poise + arm.poise + leg.poise as totalpoise,
helmet.weight + body.weight + arm.weight + leg.weight as totalweight
from
helmet
inner join
body on 1=1
inner join
arm on 1=1
inner join
leg on 1=1
where
helmet.weight + body.weight + arm.weight + leg.weight <= 10
order by
totalpoise desc
limit 5
结果:
+-------+-------+-------+-------+----------+-------------+
| hname | bname | aname | lname | totaldef | totalweight |
+-------+-------+------ +-------+----------+-------------+
| head2 | body2 | arm1 | leg3 | 23 | 9.8 |
| head1 | body2 | arm2 | leg3 | 23 | 9.5 |
| head3 | body2 | arm3 | leg3 | 22 | 9.5 |
| head1 | body2 | arm1 | leg3 | 22 | 9.1 |
| head2 | body2 | arm3 | leg3 | 21 | 8.9 |
+-------+-------+-------+-------+----------+-------------+
每个表格大约有100行,因此可能的结果是1亿多行。查询需要很长时间。我不确定这与我的硬件、数据库类型或查询有关。
附注:我使用HDD硬盘并拥有8GB的内存。我已在MySQL和PostgreSQL上进行了测试。
更新:我还没有创建索引。
这是解释计划吗? explain plan 需要多长时间? 这取决于输入。 在MySQL上,需要几分钟到几小时。 在PostgreSQL上,需要约30秒至2分钟。
更新2:我的表格从不更改。那么我可以将所有结果存储在一个表格中吗?这有帮助吗?
更新3:我考虑分区。这可能会快得多,但问题是如果某个下分区中的[装甲套装]的总防御值高于上分区中的[装甲套装]。 例如:
[head1,arm1,body1,leg1][totaldef 25][totalweight 9.9]
[head2,arm2,body2,leg2][totaldef 20][totalweight 11.0]
因为它位于其他分区,所以分区总重量>10会错过那个[装甲套装]。
这是CSV文件,供任何想要测试的人使用。CSV文件
更新4 我认为最快的方法是创建物化视图,但我猜性能的关键是对其进行排序。我不知道哪种排序可以帮助物化视图或索引,但我将它们都排序了,这很有帮助。
我没想到会得到这么多帮助。谢谢。
helm_id,body_id,arm_id,leg_id,weight_sum,def_sum
的结构。 - Lemjur