Sql server 慢速选择的SQL索引

Sql server 慢速选择的SQL索引,sql-server,Sql Server,仍然在学习SQL,我有下面的选择,工作得很好,但是,我想加快一点。根据我对索引的理解(很少),我需要有一个唯一的ID列,索引才能产生效果 我的表都没有唯一的ID,即使列的组合也不会产生唯一的ID 所以我的问题是索引可以帮助我吗?如果是,我如何实施? 或者有没有更好的方法来编写下面的内容以更快地执行 SELECT * FROM ( SELECT *, (SELECT SITE FROM SITES WHERE SITES.SITE_ID = tblJOIN.SITE_ID

仍然在学习SQL,我有下面的选择,工作得很好,但是,我想加快一点。根据我对索引的理解(很少),我需要有一个唯一的ID列,索引才能产生效果

我的表都没有唯一的ID,即使列的组合也不会产生唯一的ID

所以我的问题是索引可以帮助我吗?如果是,我如何实施? 或者有没有更好的方法来编写下面的内容以更快地执行

SELECT * FROM (
    SELECT *,
        (SELECT SITE FROM SITES WHERE SITES.SITE_ID = tblJOIN.SITE_ID ) AS SITE, (SELECT ARTICLE FROM ARTICLES  WHERE ARTICLES.ARTICLE_ID = tblJOIN.ARTICLE_ID ) AS ARTICLE
    FROM tblJOIN) a
    INNER JOIN RANGE ON a.SITE=RANGE.SITE_ID AND a.ARTICLE=RANGE.ARTICLE_ID;
除了创建(唯一的)主键之外(使用SSM)。您还需要基于该键创建聚集索引。这可以通过
SSMS
设计表或命令来完成

使用站点id作为主键为表站点创建(群集)主键的示例代码(必须使其唯一):

增编:

我的所有表都没有唯一的ID,即使是列的组合也是如此 不会产生唯一的ID

这并不意味着一个深思熟虑的设计。看起来您有一些字段要用作唯一ID,例如您的SITES.SITE_ID。并不是所有表都必须有一个主唯一ID,但表示“实体”的表应该有一个

除了创建(唯一)主键(使用SSM)之外。您还需要基于该键创建聚集索引。这可以通过
SSMS
设计表或命令来完成

使用站点id作为主键为表站点创建(群集)主键的示例代码(必须使其唯一):

增编:

我的所有表都没有唯一的ID,即使是列的组合也是如此 不会产生唯一的ID

这并不意味着一个深思熟虑的设计。看起来您有一些字段要用作唯一ID,例如您的SITES.SITE_ID。并不是所有表都必须有一个主唯一ID,但表示“实体”的表应该有一个

原始的

SELECT * 
FROM ( SELECT *
            , (SELECT SITE FROM SITES WHERE SITES.SITE_ID = tblJOIN.SITE_ID ) AS SITE
            , (SELECT ARTICLE FROM ARTICLES  WHERE ARTICLES.ARTICLE_ID = tblJOIN.ARTICLE_ID ) AS ARTICLE 
        FROM tblJOIN
     ) a
FROM RANGE r 
JION tblJOIN j
  ON a.SITE    = r.SITE_ID 
 AND a.ARTICLE = r.ARTICLE_ID;
我不确定我会回来看看这个原始文件

SELECT * 
FROM ( SELECT *
            , (SELECT SITE FROM SITES WHERE SITES.SITE_ID = tblJOIN.SITE_ID ) AS SITE
            , (SELECT ARTICLE FROM ARTICLES  WHERE ARTICLES.ARTICLE_ID = tblJOIN.ARTICLE_ID ) AS ARTICLE 
        FROM tblJOIN
     ) a
FROM RANGE r 
JION tblJOIN j
  ON a.SITE    = r.SITE_ID 
 AND a.ARTICLE = r.ARTICLE_ID;

不确定我是否会回来看看这个索引,所有的子选择和子查询都会将大量记录拉入内存,而您只是在最后一个外部联接中过滤掉这些记录。这将立即更快地返回相同的结果集。执行计划应该为您提供更多有用的提示,说明索引在哪里可能有用

SELECT 
  J.*,
  R.*,
  S.[SITE] AS [SITE], 
  A.ARTICLE AS ARTICLE
FROM 
  [tblJOIN] AS J --The two original subselects joined here; good place to start.
JOIN --Rather than a subselect (row by row processing) added two joins...
  [SITES] AS S
    ON
      S.[SITE_ID] = J.[SITE_ID]
JOIN --...because joins are set based. Then SELECTed the needed fields from each.
  [ARTICLES] AS A
    ON
      A.[ARTICLE_ID] = J.[ARTICLE_ID]
 JOIN --Then just added your last join as written.
  [RANGE] AS R
    ON 
      S.[SITE] = R.[SITE_ID]
      AND 
      A.[ARTICLE] = R.[ARTICLE_ID];

另外,如果您对表结构有什么要说的,那么在两个不同数据点的表中包含名为SITE_ID和ARTICLE_ID的字段并不是最佳做法。从原始查询中,tblJOIN.SITE\u ID RANGE.SITE\u ID和ARTICLE\u ID也是如此。此外,让名为anywhere\u ID的字段实际上不是标识符列也不是最佳做法

撇开索引不谈,所有的子选择和子查询都会将大量记录拉入内存中,而您只是在最后一次外部联接中过滤掉这些记录。这将立即更快地返回相同的结果集。执行计划应该为您提供更多有用的提示,说明索引在哪里可能有用

SELECT 
  J.*,
  R.*,
  S.[SITE] AS [SITE], 
  A.ARTICLE AS ARTICLE
FROM 
  [tblJOIN] AS J --The two original subselects joined here; good place to start.
JOIN --Rather than a subselect (row by row processing) added two joins...
  [SITES] AS S
    ON
      S.[SITE_ID] = J.[SITE_ID]
JOIN --...because joins are set based. Then SELECTed the needed fields from each.
  [ARTICLES] AS A
    ON
      A.[ARTICLE_ID] = J.[ARTICLE_ID]
 JOIN --Then just added your last join as written.
  [RANGE] AS R
    ON 
      S.[SITE] = R.[SITE_ID]
      AND 
      A.[ARTICLE] = R.[ARTICLE_ID];

另外,如果您对表结构有什么要说的,那么在两个不同数据点的表中包含名为SITE_ID和ARTICLE_ID的字段并不是最佳做法。从原始查询中,tblJOIN.SITE\u ID RANGE.SITE\u ID和ARTICLE\u ID也是如此。此外,让名为anywhere\u ID的字段实际上不是标识符列也不是最佳做法

按照标准,每个表都应该有一个
Id
列,该列带有
AUTO_INCREMENT
,这将是行的标识符。据我所知,唯一的例外是关系表(多对多),“我需要一个唯一的ID列,索引才能起作用?”;不,那不是真的。您确实需要一个唯一的列才能创建
聚集索引
,但是
索引
不需要;它们仍然可以提高性能。然而,这是一个非常好的(标准实践),在你的桌子上有某种唯一的标识符,所以我仍然强烈建议这样做;拥有一个
聚集索引
可以给你带来更多帮助。你的子查询是大的红色标记。除了创建一个(唯一的)主键外,还可以尝试删除它们。您还需要使其成为基于该键的聚集索引。这可以通过SSM或命令来完成。请尝试共享一些测试数据,以便我们可以测试“寻求性能帮助的问题应包括所涉及表的DDL、DML以及测试数据。如果您的测试数据很大,请尝试编写表的架构和统计信息的脚本(右键单击数据库->生成脚本->选择特定的数据库对象->在下一个屏幕中选择高级并选择脚本统计信息)并将其粘贴到问题中。使用此信息,任何人都可以复制您面临的同一问题。否则,回答您的问题会变得非常困难。粘贴服务器版本也会有帮助”根据标准,每个表都应该有一个
Id
列,该列带有
AUTO_INCREMENT
,这将是行的标识符。据我所知,唯一的例外是关系表(多对多)。“我需要一个唯一的Id列,索引才能起作用?”;不,那不是真的。您确实需要一个唯一的列才能创建
聚集索引
,但是
索引
不需要;它们仍然可以提高性能。然而,这是一个非常好的(标准做法)在您的表上有某种唯一标识符,因此我仍然强烈建议这样做;拥有
聚集索引可以帮助您做得更多。您有大红色标记的子查询。除了创建(唯一)外,尝试删除它们主键。您还需要将其作为基于该键的聚集索引。这可以通过SSMS或命令完成。请尝试共享一些测试数据