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 |
+------+---------+-----+--------+ +------+---------+-----+--------+`
我正在寻找总重量< =输入的最高总保额
像这样:总重量< = 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行,因此可能的结果是100米行.查询需要很长时间.我不确定这是关于我的硬件或数据库或查询的类型.
P.S:我使用HDD并且有8GB的内存.我曾在MysqL和Postgresql上测试过.
更新
我还没有创建索引.
这是解释计划吗?
explain plan
多久时间?
这取决于输入.
在MysqL上,它只需几分钟 – 几个小时.
在Postgresql上大约需要30秒–2分钟.
更新2我的表永远不会改变.那么我可以将所有结果存储在一个表中吗?有帮助吗?
更新3我想到分区.它可能要快得多,但问题是如果下部分区中的某些[装甲设置]在上部分区中的totaldef超过[armor set].
例:
[head1,arm1,body1,leg1][totaldef 25][totalweight 9.9]
[head2,arm2,body2,leg2][totaldef 20][totalweight 11.0]
所以分区总重量> 10会错过[盔甲套装]因为它在其他分区中.
更新4我认为最快的方法是创建materialized view,但我认为性能的关键是排序.我不知道哪种类型可以帮助物化视图或索引,但我对它们进行了排序,这很有帮助.
我没想到会得到很多像这样的帮助.谢谢.
解决方法:
具有适当索引的materialized view表现相当不错,在我老化的SSD桌面上使用Postgresql配置库存1.8秒:
create materialized view v as
select
h.name as hname, b.name as bname, a.name as aname, l.name as lname,
total_poise, total_weight
from
helmet h
cross join
body b
cross join
arm a
cross join
leg l
cross join lateral (
select
h.weight + b.weight + l.weight + a.weight as total_weight,
h.poise + b.poise + l.poise + a.poise as total_poise
) total
order by total_poise desc, total_weight
;
create index v_index on v (total_poise desc, total_weight);
执行和分析:
select *
from v
where total_weight <= 10
order by total_poise desc, total_weight
limit 5
;
hname | bname | aname | lname | total_poise | total_weight
-----------------------+--------------------------+------------------------+--------------------------+-------------+--------------
Fume Sorcerer Mask+10 | Moon Butterfly Wings+5 | Velstadt`s Gauntlets+5 | Prisoner`s Waistcloth+10 | 20 | 9.4
Fume Sorcerer Mask+10 | Lion Warrior Cape+10 | Velstadt`s Gauntlets+5 | Prisoner`s Waistcloth+10 | 20 | 9.5
Fume Sorcerer Mask+10 | Red Lion Warrior Cape+10 | Velstadt`s Gauntlets+5 | Prisoner`s Waistcloth+10 | 20 | 9.5
Fume Sorcerer Mask+10 | Moon Butterfly Wings+5 | Velstadt`s Gauntlets+5 | Lion Warrior Skirt+10 | 20 | 9.6
Fume Sorcerer Mask+10 | Moon Butterfly Wings+5 | Velstadt`s Gauntlets+5 | Moon Butterfly Skirt+10 | 20 | 9.6
explain analyze
select *
from v
where total_weight <= 10
order by total_poise desc, total_weight
limit 5
;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.57..11.71 rows=5 width=88) (actual time=1847.680..1847.694 rows=5 loops=1)
-> Index Scan using v_index on v (cost=0.57..11191615.70 rows=5020071 width=88) (actual time=1847.678..1847.691 rows=5 loops=1)
Index Cond: (total_weight <= '10'::double precision)
Planning time: 0.126 ms
Execution time: 1847.722 ms
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。