SQL INDEX用于慢速选择

问题描述 投票:0回答:3

还在学习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;
sql-server
3个回答
1
投票

除了索引之外,所有的子选择和子查询都会将大量记录拉入您刚刚使用上一个外部联接过滤掉的内存中。这应该立即返回相同的结果集。执行计划应该为您提供有关索引可能有用的更多有用提示。

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_ID <> RANGE.SITE_ID,同样与ARTICLE_ID。此外,将名为Anything_ID的字段实际上不是标识符列也不是最佳做法。


2
投票

除了创建(唯一)主键(使用SSMS)。您还需要根据该键创建聚簇索引。这可以通过SSMS设计表或通过命令完成。

使用site_id作为主键为表SI创建(Clustered)主键的示例代码(您必须使其唯一):

USE [yourDBname]
GO

SET ANSI_PADDING ON
GO

/****** Object:  Index [PK_SITES]    Script Date: 3/5/2018 9:19:11 AM ******/
ALTER TABLE [dbo].[SITES] ADD  CONSTRAINT [PK_SITE_ID] PRIMARY KEY CLUSTERED 
(
    [SITE_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

附录:

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

这并不意味着经过深思熟虑的设计。看起来您的字段可以用作唯一ID,例如您的SITES.SITE_ID。虽然并非所有表都必须具有主要唯一ID,但代表“实体”的表应该具有。


0
投票

一部开拓创新

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;

不确定我会回来看看这个

© www.soinside.com 2019 - 2024. All rights reserved.