2

約 3000/4000 行のテーブルが 2 つあります。テキストまたは日時を検索して結果をフィルター処理するには、左結合を使用して関係を作成する必要があります。ページネーションのために合計行を数える必要もあります。クエリを実行すると非常に遅くなります。コンソールで約 40/45 秒、Web ページで 1 分以上かかると考えてください。関係は次のとおりです。tableAの1に対して、tableBにNがあります。高速クエリの解決策はありますか? サンプル クエリは次のとおりです。

SELECT X,Y,Z, (SELECT COUNT(*) 
     FROM tableB WHERE tableB.idTa=tableA.id) AS CountTB 
FROM tableA 
LEFT JOIN tableB ON tableA.id = tableB.idA
WHERE tableA.X LIKE'%mytext%' OR tableB.Z LIKE'%mytext%' 
GROUP BY tableA.id 
ORDER BY tableA.Y LIMIT 0,10

皆さん、ありがとうございました

ON句はもちろん存在します。私の電話からのみタイプミスしました。今は正しく、非常に遅いです:)

新しい更新: 関係を LEFT JOIN から RIGHT JOIN に変更すると、かなり高速になります....なぜ??

4

3 に答える 3

1

これを突っ込んで、一般的な方向性を示すために、そのクエリを書き直す可能性があります: (私はそれが機能するとは約束しません...)

SELECT X,Y,Z, COUNT(B.id) AS CountTB
FROM tableA A
  LEFT JOIN tableB B
    USING (id)
WHERE tableA.X LIKE'%mytext%' OR tableB.Z LIKE'%mytext%' 
GROUP BY X, Y, Z
ORDER BY tableA.Y 
LIMIT 0,10

私の多くの変更に注意してください:

  1. ネストされたクエリはありません。
  2. テーブルは便宜上、エイリアスによって識別されAますB
  3. LEFT JOINはのUSING (id)短縮形ですWHERE A.id = B.id
  4. このGROUP BY節は、データがこれら 3 つの変数によってグループ化されることを指定します。これらはSELECTすべて句に含まれている必要があり、その他COUNT()のすべての項目はorなどの集計関数である必要がありますSUM()

繰り返しますが、このクエリが機能することを約束するものではありません。 ただし、そのようなクエリが一般的にどのように構築されるべきかを示す必要があります。

于 2016-06-28T14:20:34.133 に答える
0

「右側」の表からLEFT必要でない限り、使用しないでください。NULLsこの場合、あなたはそうではないと思います。

の配置は、( SELECT COUNT... )行ごとに再評価する必要があることを意味しますが、そうではありません。それを取り除きます。使用してSQL_CALC_FOUND_ROWSください。

AX と BZ で同じ部分文字列が検索されていますか? それらは常に同じ値を持っていますか?もしそうなら、そのうちの1つだけを検索してください。(LIKE '%...'クエリのコストのかかる部分です。)

を使用JOINすると、行数が増えます。GROUP BY次に、それを収縮させるために追加しました。この膨張/収縮にはコストがかかります。

COUNT(*)%mytext%」によるフィルタリングに失敗するため、「145 行の 30 ~ 39 行目」に必要なものが得られません。

AZかBZですか??

SELECT SQL_CALC_FOUND_ROWS
        a.X, a.Y,
        ( SELECT Z FROM tableB WHERE idTa = a.id AND Z LIKE'%mytext%' ) AS Z
    FROM tableA AS a
    WHERE a.X LIKE '%mytext%'
    ORDER BY a.Y
    LIMIT 0,10

SELECT FOUND_ROWS();   -- to get the "of 156 rows"

そして、あなたはこれらが必要です

tableB: INDEX(idTa)
tableA: INDEX(Y)

警告: A と B の関係 (1:多 vs 多:多) が明確でないため、この解決策は正しくない可能性があります。複数行を返す副問合せで不正が飛び出します。

だから、私はあなたに「正しい」答えを与えていないかもしれませんが、うまくいけば、あなたがもっと近づくことができるように十分な手がかりを与えました.

その後、OFFSET. 私のブログを参照してください。

これについてさらに議論したい場合は、列名を提供SHOW CREATE TABLEしてください。難読化しないでください。多くの場合、列名から意図の手がかりが得られます。

于 2016-07-01T16:34:43.333 に答える