2012-05-10 11 views
0

私はMySQLデータベースに2つのテーブルを持っています。一方のテーブルにはデフォルト値が含まれ、他方のテーブルにはオーバーライド値と追加情報が含まれます。私は、両方からすべての要素を選択するために2つの別々の作業SQL文を書いた後、オーバーライドがあるときに、デフォルト表の値を置き換えます。2つの作業用SQL文をUNION ALLと組み合わせると、mysqlが応答しなくなる

SELECT 
    d.id AS did, IFNULL(i.id, d.id) AS id, d.parent_id AS parent_id, 
    IFNULL(i.content, d.content) AS content, d.order_id AS ord 
    FROM cci d 
    LEFT JOIN instructions i ON d.order_id = i.order_id 
     AND i.parent_id = d.parent_id 
     AND i.specification_id = 'SOME ID' 
    WHERE d.parent_id = 'SOME PARENT' AND d.specification_id = '1' 
UNION ALL SELECT 
    i.id AS did, i.id AS id, i.parent_id AS parent_id, 
    i.content AS content, i.order_id AS ord 
    FROM instructions i 
    WHERE i.parent_id = 'SOME PARENT' 
    AND i.specification_id = 'SOME ID' 
    AND NOT EXISTS (SELECT 1 FROM cci d WHERE d.order_id = i.order_id AND d.parent_id = i.parent_id) 

個別に2つの部分が正常に動作しますが、それらをまとめてみると、MySQLは90%のCPUをスパイクしてフリーズします。明らかに、何かが正しく機能していない。このような凍結を引き起こす原因は何か?私の声明に何か間違いがありますか?

おかげ

EDIT:

EXPLAINの出力は次のようになります。

id | select_type   | table  | type | possible_keys | key | key_len | ref | rows | Extra 
———————————————————————————————————————————————————————————————————————————————————————————————————————— 
1 | PRIMARY    | d   | ALL | NULL   | NULL | NULL | NULL | 105 | Using where 
1 | PRIMARY    | i   | ALL | NULL   | NULL | NULL | NULL | 4 | 
2 | UNION    | i   | ALL | NULL   | NULL | NULL | NULL | 4 | Using where 
3 | DEPENDENT SUBQUERY | d   | ALL | NULL   | NULL | NULL | NULL | 105 | Using where 
NULL| UNION RESULT   | <union1,2> | ALL | NULL   | NULL | NULL | NULL | NULL | 
+0

2つのクエリのそれぞれで返されるレコードの数はいくつですか? 'UNION'クエリに' EXPLAIN'の出力を投稿できますか? – eggyal

+0

私はEXPLAINの結果を掲載しました。 – Chris

+0

あなたのテーブルに* *インデックスが定義されていませんか? – eggyal

答えて

0

問題は非最適ジョイン方式に切り替えているオプティマイザ、です。

問題はおそらくUNION ALLと一緒に「not in」です。

私はあなたがクエリを書き換えることができると思います。ここでスタートです:

SELECT (case when d.specification_id = '1' then d.id else i.id) AS did, 
     ... 
FROM cci d LEFT JOIN 
    instructions i 
    ON d.order_id = i.order_id AND 
     i.parent_id = d.parent_id AND 
     i.specification_id = 'SOME ID' left outer join 
    cci parent 
    on d.parent_id = parent.parent_id 
WHERE d.parent_id = 'SOME PARENT' AND d.specification_id in ('1', 'SOME ID') 

また、一時テーブルを使用した場合も、あなたの問題を解決するだろう。

+0

あなたが提示したコードは、私が投稿したSQL文の前半と同じ出力を与えます。私が後半を必要とするのは、specification_idとparent_idに一致するが、order_idには一致しない値があるからです。 2番目のselectステートメントは、それらを探して出力に追加することになっています。これらの補助行を取得する方法はありますか? – Chris

関連する問題