MYSQL结合查询进行优化

时间:2012-06-27 18:44:18

标签: mysql query-optimization

我想尽可能少地将几个查询组合在一起。这是我正在写的视频游戏。 注意 -spawn_id是一个实体的id,它在地图上给定位置的关卡上创建坏人。 - *来自spawns包括spawn_id,产生的最大数量的坏人(数量),以及产生它们的坏人的类型(mob_id)以及产生它们的ID以告诉它产生什么类型的坏人 游戏在线,所以Id相当于最小化查询次数

如果我可以从数量(游戏中的最大数量)中减去计数(已经在游戏中的数量)将会很好,其中产生的ID是相同的并且一起返回

如果我可以将生成的ID数量返回到spawn并将坏人的类型一起返回到像这样的一行,那会更好

选择spawn_id,COUNT(*)作为'count'来自game_moblist GROUP BY spawn_id“ 返回...

spawn_id count
======== =====
1         2

TABLE spawns包含

spawn_id quantity mob_id level
======== ======== ====== =====
1        5        1      2

mob_id poitns来表示拥有

的小怪
mob_id ...stats for mob_id
====== ===================
1      unique stats for mob#1

我想回复这样的事情:

spawn_id   quantity_to_spawn   mob_id   ...stats for mob_id
========   =================   ======
1          3                   1        unique stats for mob#1

这意味着我必须插入从怪物中选择的3行,我不介意做第二次查询,所以我可以按级别乘以统计数据,在2级游戏中创建一个坏人......基本上是2级意味着统计数据是“暴徒”表中存储的数字的两倍

到目前为止,这是我的代码,我可以完成它,但我宁愿先尝试减少查询次数。

    sql= "SELECT spawn_id, COUNT(*) as 'count' FROM game_moblist  GROUP BY spawn_id"
       connection.query(sql, function(err, spawncount, fields) {
          sql= "SELECT  * FROM spawns"
          connection.query(sql, function(err, spawns, fields) {
             for (i=0;i<spawns.length;i++){
                if (spawns[i].next_spawn < new Date().getTime()){
               for (j=0;spawncount.length;j++){
                      if (spawncount[j].spawn_id ==spawns[i].spawn_id&&spawncount[j].count<spawns[i].quantity){
                         quantity_to_spawn = spawns[i].quantity -spawncount[j].count
                         //fetch spawns[i].mob_id mob from mobs table
                         for(k=0;k<quantity_to_spawn;k++){
                         //multiply for level
                         //insert into moblist
                         }
                      }
                   }
                }
             }
          });
       });

2 个答案:

答案 0 :(得分:0)

这正是使用LEFT或INNER JOIN的原因。请阅读这些SQL函数的工作原理 - 您将以这种方式大大提升您的SQL知识!

基本思想是,如果你有两个表,比如,项目:

item      name
=====     =====
1         Sword of Ultimate Power
2         Big Freaking Gun

和地点:

location  name
========  =====
1         Fortress of Solitude
2         Quendor

然后想要一个表item_locations来跟踪哪些项目在哪些位置:

item_id    location_id
========   ============
1          2
2          1

然后你可以使用像

这样的表达式
SELECT item.name, location.name FROM items LEFT JOIN item_locations AS il ON (item.id = il.item_id) LEFT JOIN locations ON (il.location_id = locations.id)

然后您将返回如下列表:

item.name                  location.name
===============            ================
Sword of Ultimate Power    Quendor
Big Freaking Gun           Fortress of Solitude

这样做的另一个好处是,您可以将多个索引添加到各个表中,以优化实际的行查找。

您还可以使用视图来制作自动提供这些关系的新虚拟表。

答案 1 :(得分:0)

SELECT 
 spawn_id,
 quantity - COUNT(game_moblist.(spawn_id)) AS quantity_to_spawn,
 mobs.*
FROM spawn_contains
LEFT JOIN mobs USING (mob_id)
LEFT JOIN game_moblist USING (spawn_id)
GROUP BY spawn_id