0

と の 2 つのテーブルがtabAあり、 からへtabBの 1 対多の関係があります。私はクエリを持っています:tabAtabB

SELECT * FROM `tabA` LEFT JOIN `tabB` ON `tabA`.`aID` = `tabB`.`aID`

返される行は、 から への参照tabAごとに複数の重複がある大きなセットです。tabBtabA

GROUP BY行を一意の要素に制限するために使用できることを認識していますが、関数tabAを使用してカスタムフィールドを使用し、エスケープ用のGROUP_CONCAT2 つの関数と組み合わせて使用​​しない限りREPLACE(これはパフォーマンスに深刻な影響を与えます)、含まれる行の 1 つをすべて失います。tabB. クエリの例は次のようになります。

   SELECT `tabA`.*,
          GROUP_CONCAT(REPLACE(REPLACE(`tabB`.`tabBCol1`, '/', '//'), ',', '/,')) AS `tabBCol`,
          GROUP_CONCAT(REPLACE(REPLACE(`tabB`.`tabBCol2`, '/', '//'), ',', '/,')) AS `tabBCo2` 
     FROM `tabA` 
LEFT JOIN `tabB` ON `tabA`.`aID` = `tabB`.`aID` 
 GROUP BY `tabA`.`aID`

そのクエリにより、LIMIT構文を使用できるようになるため、(たとえば) 5 から始まる 5 つのエントリのみを表示できます (つまりLIMIT 5,5)。これを前のクエリに適用すると、次の 5 つのクエリではなく、関連付けの数に基づくランダムなデータ セットが取得されます。

したがって、2 番目のクエリとは別に、関連付けを使用して行をフェッチする方法はありますが、LIMIT構文の使用を許可し、過剰なREPLACE関数のパフォーマンスへの影響はありませんか?

追加

各行に複数のサブクエリを使用できますが、最初のクエリをGROUP BY構文で使用して (これによりWHERE、関連付けに任意の条件を適用できます)、N+1 選択の問題を回避する方法を見つけようとしています (ただし、この例では、私のLIMIT構文は ですLIMIT 5,5。これをはるかに大きなLIMITs (一度に最大 1000 行) に適用します)。

4

1 に答える 1

1

2 つのクエリを試してください。

// get those 5 records
SELECT * FROM Cars   WHERE some_conditon = blabla LIMIT 5;

// get all associated records from related table
SELECT * FROM Wheels WHERE car_id IN (1, 3, 5, 123, 16);

結果として、常に 2 つのクエリがあるため、N の問題は発生しません。最初のクエリに 1000 件のレコードがある場合でも、/concats/etc による結合/グループ化よりも、この単純な方法を使用する方が常に優れています。

于 2013-03-28T01:21:24.230 に答える