【问题标题】:MYSQL combining queries for optimizationMYSQL 结合查询进行优化
【发布时间】:2012-06-28 02:52:57
【问题描述】:

我想将几个查询组合成尽可能少的。这是我正在写的一个视频游戏。 笔记 -spawn_id 是在地图上给定位置的关卡上创建坏人的实体的 ID。 -* 来自 spawns 包括 spawn_id、要生成的坏人的最大数量(数量)、要生成的坏人的类型(mob_id)和一个 ID,告诉它要生成什么类型​​的坏人 游戏是在线的,所以我宁愿尽量减少查询次数

如果我可以从数量(游戏中的最大数量)中减去数量(游戏中的数量),其中生成 ID 相同并一起返回,那就太好了

如果我可以像这样将生成的生成 ID 数量和坏人的类型一起返回为一行会更好

SELECT spawn_id, COUNT(*) as 'count' FROM game_moblist GROUP BY spawn_id" 返回...

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

TABLE 生成包含

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

mob_id 指向拥有的 TABLE mobs

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 级意味着统计数据是 'mobs' 表中存储的数字的两倍

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

    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
                         }
                      }
                   }
                }
             }
          });
       });

【问题讨论】:

    标签: mysql query-optimization


    【解决方案1】:
    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
    

    【讨论】:

    • 我在数量上添加了一个括号并将表 spawn_contains 更改为 spawns SELECT spawn_id, ( quantity - COUNT( game_moblist.spawn_id ) ) AS quantity_to_spawn, mobs 。 * FROM spawns LEFT JOIN mobs USING (mob_id) LEFT JOIN game_moblist USING (spawn_id) GROUP BY spawn_id LIMIT 0 , 30 谢谢你真的帮助我理解了一些我不太熟悉的 MySQL。
    【解决方案2】:

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

    基本思想是,如果您有两个表,例如 Items:

    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
    

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

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

    【讨论】:

    • 我同意并且我尝试了以下查询 SELECT spawn_id, COUNT(*) as 'count' FROM game_moblist LEFT JOIN game_moblist ON spawns.spawn_id=game_moblist.spawn_id GROUP BY spawn_id 但它说#1066 - 不是唯一表/别名:'game_moblist' 我在一定程度上理解左连接,但在 mysql 中进行算术运算并返回一个组合行,其中数量减去计数和 sapwn id 上的左连接,然后是第二个左连接,这有点超出我的水平mob_id
    猜你喜欢
    • 2019-06-09
    • 1970-01-01
    • 2010-10-23
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    • 2020-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多