【问题标题】:SQL Inner Join IssueSQL 内部联接问题
【发布时间】:2011-12-21 07:22:02
【问题描述】:

在一个表中,有两个来自另一个表的外键。

第一个表是documents,另一个表是common

我当前的代码,

SELECT a.* FROM documents AS a INNER JOIN common AS c ON a.docId = c.id INNER JOIN common as cc ON a.statusId = cc.id

加入以获得更好的性能的最佳方式是什么?

谢谢。

【问题讨论】:

标签: sql


【解决方案1】:

您的 SQL 看起来不错。确保你的 fk 列有索引,你应该很高兴。您担心的具体原因是什么?

【讨论】:

  • 使用索引的原因是什么?我只是好奇是否有更好的方法。
  • 是的,我对索引了解不多。这些索引应该用于文档表吗?会更快吗?
  • 是的,在 a.docId 和 a.statusId 上。您可能希望拥有一个包含这两者的索引,以最大化此特定连接。
【解决方案2】:

为什么你加入公用表两次,甚至不从中选择任何列? 如果您使用连接进行过滤,您可以尝试这样做:

SELECT a.* 
FROM documents AS a 
WHERE (SELECT COUNT(*) FROM common 
       WHERE a.docId = id OR a.statusId = id)>0

然后确保 id、docId 和 statusId 被索引。

如果您只是忘记将 c 和 cc 表添加到您的列选择中,您可以,如果您还没有设置索引,请加快设置索引的速度。

【讨论】:

  • 我忘记从公用表中选择列。它应该是 a.*,c.Name, cc.Name
【解决方案3】:

选择字段不要使用select * 这可以提高跨服务器和客户端的数据流量性能,并为表设置键和索引

Select a.fieldone, a.fieldtwo FROM documents AS a 
INNER JOIN common AS c ON a.docId = c.id
INNER JOIN common as cc ON a.statusId = cc.id

【讨论】:

    【解决方案4】:

    要遵循的基本加入策略

    1) Index the joined fields. 
    2) Ensure that statistics are upto date, this way SQL wont recalculate plan and will used the cached plan
    3) Join from the smaller table to the bigger one, help sql server
    choose the best plan 
    4) Read the Query Analyser Plan, if you see a Hash Join being performed on two large tables then add a covering index to make it choose a nested loop join which is better 
    5) If a small table is joined to a large table a Hash join is so much
    better. 
    6) Avoid bookmark lookups. See this for more info http://www.sqlservercentral.com/articles/Performance+Tuning/bookmarklookups/1899/
    

    【讨论】:

    • 感谢您的信息。什么是统计数据?如何阅读查询分析器计划?什么是哈希连接?对不起我的无知。我不擅长 SQL。
    • Statistics 是数据库统计信息,sqlserver 使用这些统计信息来保证索引的新鲜度。您可以在 Query : Menu 下的 sqlserver 中看到“实际执行计划”。本文是关于hash join msdn.microsoft.com/en-us/library/aa178403(v=SQL.80).aspx 的基本解释,你不必知道但在调优查询时很有用
    【解决方案5】:

    使用 SQL 编写任何查询的方法总是不止一种,最好测试至少两个候选查询的性能。影响性能的因素有很多,其中最重要的是您使用的 SQL 产品。

    注意到common 的两个连接是semijoins,这是一个建议的替代方案:

    SELECT * 
      FROM documents AS a 
     WHERE EXISTS (
                   SELECT * 
                     FROM common AS c 
                    WHERE a.docId = c.id
                  )
           AND EXISTS (
                       SELECT * 
                         FROM common AS cc 
                        WHERE a.statusId = cc.id
                      );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-27
      • 1970-01-01
      • 2013-04-09
      • 2018-05-06
      • 2012-01-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多