实现sql从同一查询中检索多个用户名的最佳方法是什么?

时间:2018-02-22 12:07:08

标签: mysql sql performance

我有一个产品表,其中包含3列,created_user_id,updated_user_id和in_charge_user_id,所有这些都与我的用户表相关,我在其中存储用户的ID和名称。

我想构建一个有效的查询来获取相应user_id的名称。

我到目前为止构建的查询如下:

SELECT products.*, 
(SELECT name FROM user WHERE user_id = products.created_user_id) as created_user,
(SELECT name FROM user WHERE user_id = products.updated_user_id) as updated_user,
(SELECT name FROM user WHERE user_id = products.in_charge_user_id) as in_charge_user
 FROM products

此查询的问题是,如果我有30,000条记录,我每行执行3次查询。

实现这一目标的更有效方法是什么?我正在使用mysql。

4 个答案:

答案 0 :(得分:0)

对于每种类型的用户ID(创建,更新,in_charge),您将加入users表一次:

SELECT
  products.*,
  u1.username AS created_username,
  u2.username AS updated_username,,
  u3.username AS in_charge_username,
FROM products
JOIN user u1 ON products.created_user_id = u1.user_id
JOIN user u2 ON products.updated_user_id = u2.user_id
LEFT JOIN user u3 ON products.in_charge_user_id = u3.user_id

这是获取数据的最佳实践方法。 您的查询与子选择类似,但更现代的方法,我认为数据库可以更好地优化和利用。

重要:

两个表中的所有user_id字段都需要外键索引! 然后,无论表中有多少行,查询都会非常快。这需要一个支持外键的引擎,如InnoDB

LEFT JOININNER JOIN

由于其他答案提示LEFT JOIN,我不会进行左连接。 如果您在products表中有一个用户ID,则必须是user表中的链接user_id,但in_charge_user除外,它只出现一些次数。如果没有,数据将在语义上被破坏。外键确保您始终具有链接的user_id,并且只有在没有链接的产品时才能删除user_id。 JOIN相当于INNER JOIN

答案 1 :(得分:0)

您可以使用LEFT JOIN而不是subselects。

您的查询应该是:

SELECT 
    P.*,
    [CU].[name],
    [UU].[name],
    [CU].[name]
FROM products AS [P]
    LEFT JOIN user AS [CU] ON [CU].[user_id] = [P].[created_user_id]
    LEFT JOIN user AS [UU] ON [UU].[user_id] = [P].[updated_user_id]
    LEFT JOIN user AS [CU] ON [CU].[user_id] = [P].[in_charge_user_id]

答案 2 :(得分:0)

首先,您的查询应该没问题。您只需要##### xgb.Booster raw: 12.2 Kb call: xgb.train(params = param, data = test_matrix_1, nrounds = 10, print_every_n = 1) params (as set within xgb.train): max_depth = "2", eta = "0.005", nthread = "2", objective = "multi:softprob", eval_metric = "auc", num_class = "3", verbose = "2", silent = "0", silent = "1" xgb.attributes: niter callbacks: cb.print.evaluation(period = print_every_n) niter: 10 或更好user(user_id)的索引来提高性能。我想第一个存在。

其次,您可以使用user(user_id, name)

来编写此内容
LEFT JOIN

使用上述索引之一,这两种方法应具有非常相似的性能。

另请注意SELECT p.*, uc.name as created_user, uu.name as updated_user, uin.name as in_charge_user FROM products p LEFT JOIN user uc ON uc.user_id = p.created_user_id LEFT JOIN user uu ON uu.user_id = p.updated_user_id LEFT JOIN user uin ON uin.user_id = p.in_charge_user_id; 的使用。这样可以处理缺少一个或多个用户ID的情况。

答案 3 :(得分:0)

请尝试以下查询

SELECT products.*, c.name as created_user,u.name as updated_user,i.name as in_charge_user
FROM products left join user c on(products.created_user_id=c.user_id ) left join user u on(products.updated_user_id=u.user_id ) left join user u on(products.in_charge_user_id=i.user_id ) 

同样正如Gordon Linoff提到的用户表创建索引将更快地获取数据。