5

私はテーブル(約80,000行)を持っています、のように見えます

id, parentId, col1, col2, col3...
 1,     null, 'A', 'B', 'C'
 2,        1, ...
 3,        1, ...
 4,     null, ...
 5,        4, ...

(1レベルの親-子のみ)

そして、すべての依存行を取得する必要があります-

SELECT ... 
FROM table 
WHERE id = :id OR parentId = :id OR id IN (
    SELECT parentId 
    FROM table 
    WHERE id = :id
    )

しかし、なぜこのリクエストは2リクエストではなくゆっくりと動作するのですか?最初にphpでparentIdを取得した場合はどうなりますか?

$t = executeQuery('SELECT parentId FROM table WHERE id = :Id;', $id);
if ($t) {
    $id = $t;
}

$t = executeQuery('SELECT * FROM table WHERE id = :id OR parentId = :id ORDER BY id;', $id);

PS:最大は行に依存<70

PPS:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   PRIMARY product ALL PRIMARY,parentId    NULL    NULL    NULL    73415   Using where
2   DEPENDENT SUBQUERY  product const   PRIMARY,parentId    PRIMARY 4   const   1
4

5 に答える 5

2

IN等しいに変更します=

SELECT ... 
FROM table 
WHERE id = :id OR parentId = :id OR id = (
    SELECT parentId 
    FROM table 
    WHERE id = :id
    )

またはそれを結合に変更します:

SELECT ... 
FROM table 
    inner join ( 
        SELECT parentId 
        FROM table 
        WHERE id = :id
    ) s on s.parentID = table.id or s.parentID = table.parentID
于 2012-09-21T15:33:15.827 に答える
1

さて、最初のケースでは、MySQLは中間結果を作成し、それをメモリに保存してから、それを反復処理して、テーブル内の関連するすべてのIDを見つける必要があります。2番目の方法では、idと親idにインデックスを正しく作成したと仮定すると、インデックスに直接移動し、関連する行を見つけて、すぐに結果を返します。

于 2012-09-21T15:29:15.553 に答える
1

この場合、UNIONはより高速に動作します

これにより、最初にユーザーUNION INDEXにクエリを実行し、2番目に内部結合を使用して結果をマージできます。

SELECT *
FROM `table` 
WHERE id = :id OR parentId = :id
UNION
SELECT t1.*
FROM `table` t1 JOIN `table` t2 ON t2.parentId = t1.id AND t2.id = :id
于 2012-09-21T16:15:32.360 に答える
0

これは長い道のりですが、最初のケースでは、クエリのWHERE部分の「IN」ステートメントがあります。たぶん、MySQLは複数のオプションがあるかのようにクエリを最適化しようとし、2番目のケースではIN部分がないため、コンパイルされたクエリはデータベースにとってより簡単です。したがって、インデックスをより適切に利用できます。

基本的に、同じ接続での2つのクエリの場合、クエリを実行するオーバーヘッドは最小限であり、この場合は無関係である必要があります。また、一般的なサブクエリは、クエリパーサーではあまり最適化できません。代わりにJOINを使用してみてください(可能な場合)。

于 2012-09-21T15:28:28.593 に答える
0

あなたのEXPLAINために問題にもう少し光を当てるかもしれません。

を調べるEXISTSか、クエリを。として書き直しますJOIN

于 2012-09-21T15:30:33.820 に答える