0

コードのブートストラップ内で作成された 200 を超えるインスタンスを持つクラス (db 行を反映する) があります。それぞれSELECTに唯一の条件を持つ単一のクエリがありますが、ロジックでWHERE 'tblA'.'AID' = #接続された200個のWHERE句を解析する単一のクエリを作成することを考えていましたOR。その後、結果から、すでに見つかったデータで200個のオブジェクトが作成されるため、クエリは 1 つだけです。

現時点でこれをテストサーバーに実装していますが、これは効率の悪いステップではないかと考えていました.2セットのクエリを実行して、それぞれの句の半分を処理する方が良いのはいつですか(またはどのようにこれまで以上に多くのことを行う必要があります)?

さらに、次のようなものを置き換えるためにパフォーマンスエンハンサーも書いています

WHERE `tblA`.`AID` = 2 OR `tblA`.`AID` = 3 OR `tblA`.`AID` = 5 OR `tblA`.`AID` = 6 OR `tblA`.`AID` = 7

WHERE (`tblA`.`AID` >= 2 AND `tblA`.`AID` <= 3) OR (`tblA`.`AID` >= 5 AND `tblA`.`AID` <= 7)

あるいは

WHERE `tblA`.`AID` >= 2 AND `tblA`.`AID` <= 7 AND `tblA`.`AID` <> 4
4

2 に答える 2

3

個別のリストがある場合は、 を使用してinください。. .

where AID in (2, 3, 5, 6, 7, . . .)

そして、最適化については SQL エンジンに任せましょう。

最大のヒットは、クエリを解析し、大きなクエリをエンジンに送信する時間である可能性があります。リストが非常に長くなる場合は、リストを一時テーブルに入れ、テーブルにインデックスを作成し、結合を行うことを検討してください。

使用しているデータベースを指定しませんが、このアドバイスはデータベースにとらわれません。

于 2013-01-28T21:30:56.010 に答える
1

まだ DBMS を指定していません。

SQL Server の場合、これは適度に価値があるかもしれません (ただし、INとにかく長いリストを持つよりも、テーブル値パラメーターなどで結合することを検討することをお勧めします)。

SQL Server は、シークを連続した範囲にまとめるのではなく、個々のシークを個別に行います。これについては、Seek が Seek でない場合は? という記事で詳しく説明しています。ただし、以下にいくつかの例を示します。

CREATE TABLE T (X int PRIMARY KEY)

INSERT INTO T 
SELECT TOP 1000000 ROW_NUMBER() OVER (ORDER BY @@SPID)
FROM master..spt_values v1, master..spt_values v2

SET STATISTICS IO ON;

SELECT *
FROM   T
WHERE   X IN ( 1, 2, 3, 4, 5, 6, 7, 8, 9,10,
              11,12,13,14,15,16,17,18,19,20,
              21,22,23,24,25,26,27,28,29,30,
              31,32,33,34,35,36,37,38,39,40,
              41,42,43,44,45,46,47,48,49,50,
              51,52,53,54,55,56,57,58,59,60,
              61,62,63,64)

タブレット'。スキャン数 64、論理読み取り 192

SELECT *
FROM   T
WHERE   X BETWEEN 1 AND 64

タブレット'。スキャン回数 1、論理読み取り 3

64 を超える値についての記事のコメントで述べたように、定数のテーブルとネストされたループ結合をミックスに追加する、わずかに異なる計画が得られます。

于 2013-01-28T22:37:17.850 に答える