1

C# MVC アプリケーション内から SQL データベースに対して次の 2 つのクエリを実行しています。

クエリ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 + "'"

これらのクエリを実行するメソッドを実行すると、各クエリがハングし、多くの場合、アプリケーションの次のページが 1 分以上読み込まれないか、いずれかでタイムアウトになります。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 は多対 1 の関係であることがわかります。つまり、テーブル 1 に主キーがない可能性があります。tableoneid などの主キーを tableone に追加し、クラスター化インデックスにする必要があります。

ここでの別の理由は、あなたの tableone が tabletwo よりもはるかに大きく、where 句 (name = 'Name') によってさらに制限されていることだと思います。これは、大きなテーブル (tableone) を小さなテーブル (where 句を使用した tabletwo) に結合していることを意味します。SQL では、大きなテーブルを小さなテーブルに結合すると遅くなります。

私が考えることができる解決策は、「タイプ」などのいくつかの列をテーブルワンに移動して、テーブルワンをクエリの小さなセットに制限できるようにすることです

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

2,000 万行でインデックスなしで 10 ~ 15 秒? 悪くない!

Ethen Li が言うように、すべてはインデックスに関するものです。理想的な世界では、フィルター (JOIN と WHERE) または ORDER BY で機能するすべての列にインデックスを作成します。ただし、これは UPDATE と INSERT に深刻な影響を与える可能性があるため、より実用的で理想的ではない必要があります。ご提供いただいた情報を基に、次のインデックスを作成することをお勧めします。 CREATE INDEX index1 ON tableone (name); tableone.id が候補キー (行を一意に識別するもの) である場合、その上にインデックスも作成する必要があります - おそらくクラスター化され、ID の生成方法によって異なります)。

tableone (id) で UNIQUE INDEX IX1TableOne を作成します。

または

tableone (id) で UNIQUE CLUSTERED INDEX IX1TableOne を作成します。

tabletwo の場合: tableone の場合と同じことが ID に適用されます - ID に少なくとも一意のインデックスを作成します。

これらのインデックスを適切に配置すると、パフォーマンスが大幅に向上するはずです。

または、主キー制約を追加するには:

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

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

tableone では、データを物理的に並べ替える必要がある場合があるため、これには時間がかかる場合があります。したがって、アクティブなユーザーがいないメンテナンス期間中に実行してください。

于 2013-04-08T06:28:00.800 に答える