【问题标题】:Optimization: Getting SQL Query out of loop优化:让 SQL 查询脱离循环
【发布时间】:2017-12-21 16:52:14
【问题描述】:

我有两个具有 1 对 n 关系的表。 表 hobbies 有一个表用户的外键,称为“userid”

SELECT * FROM hobbies WHERE userid = 7

可以有多个结果。 表 users 包含用户个人资料数据列表,表 hobbies 包含用户爱好列表。我想打印具有每个用户爱好的多个用户的个人资料信息列表。 (爱好串联成一个字符串) 我目前有以下 sql 查询:(伪代码):

ResultSet result = executeQuery("SELECT * FROM users;");

for each returned row: executeQuery("SELECT * FROM hobbies WHERE userid =" + result.getInt("ref"));

如何使 SQL 查询脱离循环以优化大量用户的性能?

我试图做一个 LEFT JOIN,然后在 java 中而不是在 SQL 中做 WHERE ref= check 问题是我得到重复的用户,我只想在处理结果集时为每个用户打印一行 我也不确定 JOIN 是否真的提高了性能,因为我必须处理更多行。

table users
+--------+------+---------+--------+
| userid | name | country | telno  |
+--------+------+---------+--------+
|      1 | John | USA     | 123456 |
|      2 | Max  | Germany | 345678 |
+--------+------+---------+--------+

+--------------+------------+
| userid       |hobby       |
+--------------+------------+
|            1 | football   |
|            1 | basketball |
|            2 | TV         |
|            2 | Music      |
|            2 | football   |
+--------------+------------+

example output:
John, USA, 123456, {football, basketball}
Max, Germany, 345678, {TV, Music, football}

【问题讨论】:

  • 1) 您需要向我们展示这 2 个表格的 schama。 2)你需要展示一个你想看到的输出的例子
  • 所以你想把你所有的爱好都集中在一个用户身上吗?我认为你应该让我们看看你的hobbies 表和users 表以及如何连接它们。
  • 表用户行:用户 ID、姓名、国家/地区、电话号码表爱好:用户 ID、爱好示例输出:
    约翰,美国,123456,{足球,篮球}
    马克斯,德国,345678 , {电视、音乐、足球}
  • 抱歉,这看起来很难看 - 我该如何正确地换行
  • 不要添加 cmets,而是编辑问题。添加架构,编辑任何你想要的。历史被保留。

标签: java mysql sql loops optimization


【解决方案1】:

这很可能是最快的解决方案

SELECT name, country, telNo, GROUP_CONCAT(hobby)
FROM users u LEFT JOIN hobbies h ON u.id = h.userId
GROUP BY name, country, telNo

有关格式选项,请参阅https://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_group-concat

它只对最终输出有用,例如,如果您的爱好包含逗号,您将无法唯一解析它们。

【讨论】:

  • 谢谢。这就是我需要的。没有使用 Group_Concat 函数
【解决方案2】:

你可以试试:

SELECT h.userid, h.allyouneed FROM hobbies h, users u WHERE h.userid =u.userid

在一个查询中获取信息

【讨论】:

  • 阅读有关 OP 尝试 JOIN 的信息。为什么这比 JOIN 更好????
  • 相当于Join,没有区别。
  • 有区别,但正如你所说,如果他尝试加入,加入会有什么不同
【解决方案3】:
"SELECT * FROM hobbies h join users u on h.userid = u.userid WHERE userid = ?"

preparedStatement.setInt(result.getInt("ref"));

然后,您可以将所有爱好保存到类似于下面“书籍”示例的列表中。

public static List<String> selectAll() throws SQLException {
        PreparedStatement ps = null;
        ResultSet rs = null;
        // THE LIST OF BOOKS YOU WILL RETURN
        List<String> books = new ArrayList<>();
        String sql = "SELECT BOOK FROM BOOKs";

        try(Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bookshop", "root", "");){

            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();

            while(rs.next()){
                String book= rs.getString ("BOOK");
                // ADD BOOK TO THE LIST
                books.add(book);
            }
        }
        finally{
            ps.close();
            rs.close();
        }
        // RETURN LIST OF ALL BOOKS
        return books;
    }

【讨论】:

    【解决方案4】:
    SELECT u.userid,u.name,u.country GROUP_CONCAT(hobby SEPARATOR ',') 
    FROM hobbies as h join users as u on h.userid=u.userid 
    where h.userid = ? GROUP BY u.userid,u.name,u.country;
    

    假设您在hobbiesusers 之间有关系。该查询将连接连接表的hobby 的列,并且每行将有一个唯一用户。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-08
      • 1970-01-01
      相关资源
      最近更新 更多