1

我正在 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)
4

2 回答 2

3

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

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

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

我能想到的解决方案是,也许您可​​以将一些列(例如“类型”)移动到 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 + "'"

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

于 2013-04-06T22:51:07.117 回答
2

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

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

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

或者

CREATE UNIQUE CLUSTERED INDEX IX1TableOne ON tableone (id);

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

有了这些索引,您应该会发现显着的性能改进。

或者添加主键约束:

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

ALTER TABLE tabletwo 添加约束 pktabletwo PRIMARY KEY CLUSTERED (id);

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

于 2013-04-08T06:28:00.800 回答