【问题标题】:SQL Index Table JoinSQL 索引表连接
【发布时间】:2013-03-29 04:03:24
【问题描述】:

我正在我的 C# MVC 应用程序中针对 SQL 数据库执行以下两个查询。

查询1

SELECT tableone.id, name, time, type, grade, product, element, value
FROM dbo.tableone INNER JOIN dbo.tabletwo ON dbo.tableone.id = dbo.tabletwo.id
Where name = '" + Name + "' Order By tableone.id Asc, element

查询2

Select DISTINCT element FROM dbo.tableone
INNER JOIN dbo.tabletwo ON dbo.tableone.id = dbo.tabletwo.id
Where name = '" + Name + "'"

在运行执行这些查询的方法时,每个查询都会挂起,并且我的应用程序的下一页通常不会加载超过一分钟,或者会超时。当我在 SQL Server 中运行相同的查询时,每个查询都需要 10 到 15 秒才能运行,这仍然太长了。

我怎样才能加快它们的速度?我从未创建过 SQL 索引,我不确定如何为每个索引创建它,或者这是否是正确的追求路径。

Tableone 目前有 20808805 行 3 列,tabletwo 有 597707 行 6 列。

桌面

id(int, not null)
element(char(9), not null)
value(real, null)

表二

id(int, not null)
name(char(7), null)
time(datetime, null)
type(char(5), null)
grade(char(4), null)
product(char(14), null)

【问题讨论】:

  • 您需要为两个表提供表结构,以便我们提供帮助。您的 C# 代码也会有所帮助。
  • @rontornambe 我已经提供了上面的结构。
  • 是的,名称索引会修复它。感知到的 10 到 15 秒不包括处理所有结果集。如果您使用的是管理工作室,它只会显示/查询前 X 行。
  • 请正确参数化您的查询。您的代码是可注入的。

标签: c# sql sql-server join


【解决方案1】:

首先,正如@Robert Co 所说,tabletwo.name 上的索引将有助于提高性能。

另外,tableone.id 和 tabletwo.id 上是否有索引?我会假设有,因为它们看起来像主键。如果没有,您肯定需要在它们上放置索引。我可以看到 tableone 到 tabletwo 是一个多对一的关系,这意味着你可能没有 table one 上的主键。 您真的需要在tableone上添加一个主键,例如tableoneid,并使其成为聚集索引!

我认为这里的另一个原因是,您的 tableone 比 tabletwo 大得多,后者受到 where 子句(name = 'Name')的进一步限制。这意味着您正在将一个大表 (tableone) 连接到一个小表(带有 where 子句的 tabletwo)。 在 SQL 中,将大表连接到小表会很慢。

我能想到的解决方案是,也许你可以将一些列,例如'type',移动到tableone,这样你就可以在查询中将tableone限制为一个小集合

Select DISTINCT element FROM dbo.tableone
INNER JOIN dbo.tabletwo ON dbo.tableone.id = dbo.tabletwo.id
Where tableone.type = 'some type' and name = '" + Name + "'"

我不太确定这些建议如何适合您的数据模型,我只是希望它们能有所帮助。

【讨论】:

    【解决方案2】:

    10 到 15 秒,2000 万行且没有索引?这还不错!

    正如 Ethen Li 所说,一切都与索引有关。在理想情况下,您将在过滤器(JOIN 和 WHERE)或 ORDER BY 中的所有列上创建索引。但是,由于这可能会严重影响 UPDATE 和 INSERT,因此您需要更加实用且不太理想。根据您提供的信息,我建议创建以下索引: CREATE INDEX index1 ON tableone(名称); 如果 tableone.id 是您的候选键(唯一标识行的键),您还应该在其上创建一个索引 - 可能是集群的,这取决于 ID 的生成方式):

    CREATE UNIQUE INDEX IX1TableOne ON tableone (id);

    或者

    在 tableone (id) 上创建唯一的聚集索引 IX1TableOne;

    对于 tabletwo:同样适用于 ID 和 tableone - 在 ID 上至少创建一个 unqiue 索引。

    有了这些索引,您应该会发现性能有了显着提升。

    或者添加主键约束:

    ALTER TABLE tableone ADD CONSTRAINT pktableone PRIMARY KEY CLUSTERED (id);

    ALTER TABLE tabletwo ADD CONSTRAINT pktabletwo PRIMARY KEY CLUSTERED (id);

    在 tableone 上,这可能需要一段时间,因为可能必须对数据进行物理重新排序。因此,请在没有活跃用户的维护期间执行此操作。

    【讨论】:

      猜你喜欢
      • 2013-12-01
      • 2012-06-03
      • 2017-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-02
      • 1970-01-01
      • 2011-06-25
      相关资源
      最近更新 更多