我有一个产品表,其中包含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。
答案 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 JOIN
或INNER 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提到的用户表创建索引将更快地获取数据。