0
SELECT  A.Id, AMerge.FeildA, AMerge.FeildB, AMerge.FeildC, BMerge.FeildD, BMerge.FeildE, BMerge.FeildF, 
FROM 

    (SELECT Id, FieldA, FieldB, FieldC from A1
    UNION ALL 
    SELECT Id, FieldA, FieldB, FieldC from A2
    ) AS A
    INNER JOIN 
    (
    SELECT Id, FieldD, FieldE, FieldF FROM B1
    UNION ALL 
    SELECT Id, FieldD, FieldE, FieldF FROM B2
    )  AS B

ON A.Id = B.Id

ここで、A の n = 8102869、B の n = 17935860 で、テーブル サイズは n=17935860 になります。

このクエリをより効率的にリファクタリングするにはどうすればよいですか、または上記のクエリのパフォーマンスを向上させるために、テーブルまたはデータベースに対してどのようなプロセスを実行できますか?

4

2 に答える 2

1

クエリプランを投稿できますか?

すべてのテーブルの id にクラスター化インデックスがあることを確認し、次のようにリファクタリングすると速度が向上する可能性があります。クエリに多くのマージ結合があり、並べ替えがないことが、おそらくこれから得られる最善の計画です。

Select
  a1.Id, a1.FieldA, a1.FieldB, a1.FieldC, b1.FieldD, b1.FieldE, b1.FieldF
From 
  A1 Inner Join B1 On A1.ID = B1.ID
Union All
Select
  ...
From
  A2 Inner Join B1 On A2.Id = B1.ID 
Union All 
Select
  ...
From
  A1 Inner Join B2 On A1.Id = B2.ID
Union All
Select
  ...
From
  A2 Inner Join B2 On A2.ID = B2.ID

また、この mysql および sql-server にタグを付けました。ここで Sql Server について話しているのですが、mysql の内外について十分に知りません

于 2012-11-08T23:24:21.330 に答える
0

まず、すべてのテーブルにクラスター化インデックスを作成する必要があります。クラスター化インデックスがないと、テーブルはヒープになり、クエリはテーブル スキャンを実行します。これが、すべての行をチェックできる唯一の方法です。

次に、結合で使用するすべての列を少なくともカバーする(複雑/多列)インデックスが必要です。理想的には、最も粒度の高い列を最初に使用します。

したがって、この SQL がない場合、各テーブルの列数を掛け合わせて、結果の一時テーブルを作成しようとします。

したがって、1 つのテーブルに 100000 行があり、別のテーブルに 10000 行ある場合、インデックスなしで計算された行サイズは 1000000000 行になります。天は、作成される一時テーブルのサイズを知っています!

インデックス(および最新の統計)を使用すると、あるテーブルに100行、別のテーブルに10行があり、一致する可能性が高い場合、SQLは1000行を推定します。一時データベースに喜んで保存できるものは、言うまでもなく、はるかに高速に実行できます。

于 2012-11-09T16:09:41.343 に答える