优化SQL连接单列,在另一个表中包含多个列

时间:2014-12-19 18:31:42

标签: sql sql-server performance

我有两张桌子。

common_products

  • ID
  • 产品
  • owner_uid
  • backup_uid
  • manager_uid

ss_users

  • 用户ID
  • 的firstName
  • lastName
  • 电子邮件

我想获得所有所有者,备份和经理的姓名/电子邮件列表。

我正在使用下面的查询,但是想知道是否有更有效的方法来查询表格。

工作查询:

SELECT DISTINCT email,
                ( firstName + ' ' + lastName ) AS userFull,
                lastName
FROM   common_products cp
       LEFT OUTER JOIN ss_users u
                    ON u.userID = cp.owner_uid
UNION
SELECT DISTINCT email,
                ( firstName + ' ' + lastName ) AS userFull,
                lastName
FROM   common_products cp
       LEFT OUTER JOIN ss_users u
                    ON u.userID = cp.backup_uid
UNION
SELECT DISTINCT email,
                ( firstName + ' ' + lastName ) AS userFull,
                lastName
FROM   common_products cp
       LEFT OUTER JOIN ss_users u
                    ON u.userID = cp.manager_uid 

是否有更优化的方式来查询数据库?

4 个答案:

答案 0 :(得分:3)

我怀疑这个版本可能会更快:

select u.email, (u.firstName+ ' '+u.lastName) AS userFull, u.lastName
from ss_users u
where exists (select 1 from common_products cp where u.userID = cp.owner_uid) or
      exists (select 1 from common_products cp where u.userID = cp.backup_uid) or
      exists (select 1 from common_products cp where u.userID = cp.manager_uid);

然后为了获得最佳效果,请添加三个索引:common_products(owner_uid)common_products(backup_uid)common_products(manager_uid)

这将消除重复消除(因为您使用的是union),而exists应该至少与join一样快。

答案 1 :(得分:0)

我要简化它,但JOIN是重要的部分。我会留给你调整SELECT部分。

SELECT DISTINCT owner.email AS owner_email, backup.email AS back_email, manager.email AS man_email
FROM common_product cp LEFT JOIN ss_users owner on owner.userID = cp.owner_uid
LEFT JOIN ss_users backup on backup.userID = cp.backup_uid
LEFT JOIN ss_users manager on manager.userID = cp.manager_uid

答案 2 :(得分:0)

确保common_products的owner_uid,backup_uid和manager_uid字段以及ss_users的userID字段都有索引,您可以通过包含索引所需的列来进一步提高性能。

SELECT DISTINCT
    user_owner.email [OwnerEmail],user_owner.firstName + ' ' + user_owner.lastName [OwnerUserFull], user_owner.lastName [OwnerLastName],
    user_backup.email [BackupEmail],user_backup.firstName + ' ' + user_backup.lastName [BackupUserFull], user_backup.lastName [BackupLastName],
    user_manager.email [ManagerEmail],user_manager.firstName + ' ' + user_manager.lastName [ManagerUserFull], user_manager.lastName [ManagerLastName]
FROM   common_products cp
LEFT OUTER JOIN ss_users user_owner ON user_owner.userID = cp.owner_uid
LEFT OUTER JOIN ss_users user_backup ON user_backup.userID = cp.backup_uid
LEFT OUTER JOIN ss_users user_manager ON user_manager.userID = cp.manager_uid

答案 3 :(得分:-1)

我已经习惯了SQL fu,但我认为这应该有效:

SELECT DISTINCT email,
    (firstName+ ' '+lastName) AS userFull,
    lastName 
FROM common_products cp 
INNER JOIN  ss_users u 
ON (u.userID = cp.owner_uid OR u.userID = cp.backup_uid OR u.userID = cp.manager_uid)