避免巨大的中间查询连接结果(1.33615E + 35行)

时间:2010-09-16 21:30:57

标签: database

我需要一个查询来阻止产生1.34218E + 35结果的连接!

我有一张桌子item(大约8k物品;例如Foo的盾牌,酒吧的武器),每个物品是9种不同的item_type(护甲,武器等)之一。每个项目在item_attribute中都有多个条目(例如,伤害,防御)。这是一个伪代码表示:

Table item (
 item_id autoincrement,
 ...
 item_type_id char,    --- e.g. Armor, Weapon, etc
 level int             --- Must be at least this level to wear this item
);

Table item_attribute (
 item_id int references item(item_id),
 ...
 attribute char        --- e.g. Damage, Defense, etc
 amount int            --- e.g. 100
)

现在,一个角色一次佩戴9件物品(Armor,Weapon,Shield等各一件),我称之为设置。我想构建一个最大化属性的设置列表,但是具有最小的另一个属性。在示例中:对于字符级别100,在sum(defense of all items) >= 100

的位置显示前10个设置

天真的做法是:

select top 10
 q1.item_id,q2.item_id,q3.item_id,..., q1.damage+q2.damage+q3.damage... as damage
from
 (select item_id from item where item_type = 'Armor' 
     and level <= 100) as q1
 inner join (select item_id from item where item_type = 'Shield' 
     and level <= 100) as q2 on 1 = 1
 inner join (select item_id from item where item_type = 'Weapon' 
     and level <= 100) as q3 on 1 = 1
 ...
where
 q1.defense+q2.defense+q3.defense+... >= 100
order by
 q1.damage+q2.damage+q3.damage,... descending

但是,因为item中有大约8k项,这意味着DBMS排序的结果大小接近8000 ^ 9 = 1.34218E + 35种不同的设置!还有更好的方法吗?

3 个答案:

答案 0 :(得分:1)

我认为您的问题可以使用integer linear programming来解决。我建议将数据从数据库中提取出来,并将其提供给一个高度优化的解算器,这些求解器是由花费很长时间研究算法的人编写的,而不是尝试用SQL编写自己的求解器。 / p>

答案 1 :(得分:0)

你不能只加入#最强大的物品吗?应该大大减少收集规模。从逻辑上讲,最高项目的总和应该提供最高的组合。

答案 2 :(得分:0)

我要做的第一件事就是隔离你的物品。不要将整个设置视为一个整体,而是查看各个项目的总和。除非您的项目与彼此互动(设置奖金),否则您只需最大化统计数据A并最小化一个广告位的统计数据B,并为您的设置中的每个项目广告位重复该过程。这将大大降低查询的复杂性,即使它意味着更多的查询。从长远来看,它应该让事情变得更快。

要问自己的另一件事是获得统计数据A获得统计数据B(你想要失去的人数)的价值是多少?如果你可以获得1000 A,而且只需要获得1 B,这可能是值得的。但是,获得10 A怎么样,但你必须获得9 B才能做到这一点?现在事情发生了一些变化。

如果您坚持使用A:B比率,您可以单独执行每个插槽,并将每个单独的结果连接到一个查询中。