【问题标题】:SQL Server : How to improve a 3 join query using costly Non clustered Index SeekSQL Server:如何使用昂贵的非聚集索引搜索改进 3 连接查询
【发布时间】:2011-12-19 06:07:06
【问题描述】:

我有一个查询,它对 3 个表进行内部连接。

SELECT DISTINCT A.ID, <OTHER 'A' FIELDS> 
FROM C 
LEFT JOIN B ON C.Bin_ID = B.Bin_ID 
LEFT JOIN A ON B.App_ID = A.App_ID  
WHERE
   ((A.App_NAME LIKE '%%') AND (B.App_ID IS NOT NULL))  
ORDER BY 
    A.App_NAME ASC

上述表格中的数据->

  • 表 A:8000 行
  • 表 B:900000 行
  • 表 C:10,00,000 行

以下是 SQL Server 查询计划中显示的统计信息:

这里使用了两个代价高昂的索引查找,上面的索引查找具有以下统计信息:

Object: B.App_ID [non clustered index, non unique] 
Seek Predicate: B.App_ID = A.App_ID[clustered index,unique]

底部索引搜索具有以下统计信息:

Object: C.Bin_ID [non clustered index, non unique] 
See Predicate: C.Bin_ID = B.Bin_ID[clustered index,unique]

现在这个查询平均需要 5 分钟才能执行,我无法弄清楚应该怎么做才能让它更快,因为查询已经使用了索引搜索。 {所有连接都是结果集所必需的}。需要帮助!

【问题讨论】:

  • 好的,首先:B.App_ID 被索引了吗?所有用作 JOIN 条件的列(外键列)都被索引了吗?其次:A.App_NAME LIKE '%%' 是 100% 保证 没有索引 可以使用 - 您不能期望搜索条件% 开始要快 - 永远不要。
  • 是 B.App_ID 被索引(非聚集,非覆盖)并且所有用于连接条件的列都是外键列。这是否意味着 LIKE '%%' 索引将不会被使用,尽管查询计划显示索引搜索并且在计划中的任何地方都没有索引/表扫描?
  • 所有其他外键列呢? (Bin_ID 在 B 和 C 上,App_ID 在 A 和 B 上)

标签: sql-server-2005 join clustered-index non-clustered-index


【解决方案1】:

看起来您只从表 A 中获取列,并且只检查表 B 中的现有行。

我想这会给你同样的结果,而且可能会更快一点:

SELECT A.ID--, <OTHER 'A' FIELDS> 
FROM A
WHERE
   A.App_NAME LIKE '%%' AND 
   A.App_ID IN (SELECT B.App_ID
                FROM B
                  INNER JOIN C
                    ON B.Bin_ID = C.Bin_ID)
ORDER BY 
    A.App_NAME ASC

【讨论】:

  • 嘿,问题是我必须在我的查询中加入这三种方式,因为我有一个 where 子句片段,它可以包含这三个子句中的任何表(这个 where 子句片段被传递给我的查询方法)
  • @BhuvneshPratap 你有一个“三向连接”。只需将过滤表 B 和 C 的 where 子句添加到子查询即可。
猜你喜欢
  • 1970-01-01
  • 2013-08-20
  • 2012-10-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-01
  • 2017-04-01
  • 1970-01-01
相关资源
最近更新 更多