2008年12月11日

[mysql 14706] UNIONしたテーブルとJOINする際にインデックスが使われずテーブルスキャンになるのを回避する方法をご存じの方はご教示いただけますと幸いです。

こんにちは。
株式会社ビービットの玉越です。

UNIONで悩んでいます。
たぶん解決不能と思うのですが、解決不能なのかどうかご存じの方はご教示いただけますと幸いです。
長文で失礼致します。

■前提

構造の異なるテーブルtableA, tableBがあります。
これらとtableCをJOINする必要があります。
インデックスは適切に張っています。

tableA
id
C_id
time
description

tableB
id
C_id
time
(←descriptionがない)

tableC
id
time

■問題例1

SELECT
union_table.description
FROM
( SELECT
tableA.C_id,
tableA.description
FROM
tableA
UNION ALL
SELECT
tableB.C_id,
NULL
FROM
tableB
) AS union_table,
tableC
WHERE
union_table.C_id = tableC.id

union_table.C_idは、tableA.C_idかtableB.C_idのどちらかです。
なので、インデックスを効果的に使ってくれると期待します。
ところが、この方法ではtableA, tableBをテーブルスキャンするようです。

( .. UNION ALL .. )をすると、その中までは見てくれなくなるようです。

http://q.hatena.ne.jp/1198431011にも同様のことがあります。

■解決案1

上記にある通り、下記のようにすればよいようです(これから実験します)

SELECT
tableA.time
FROM
tableA,
tableC
WHERE
tableA.C_id = tableC.id
UNION ALL
SELECT
tableB.time
FROM
tableB,
tableC
WHERE
tableB.C_id = tableC.id

一度まとめテーブルを作るのではなく、結果をそれぞれ作ってからまとめる、
という方法です。

■解きたい問題

上記だけであれば問題は解決するのですが、私が行いたいのは下記です。

SELECT
union_table.description
FROM
( SELECT
tableA.C_id,
tableA.time,
tableA.description
FROM
tableA
UNION ALL
SELECT
tableB.C_id,
tableB.time,
NULL
FROM
tableB
) AS union_table,
tableC
WHERE
union_table.C_id = tableC.id
AND tableC.time - union_table.time = (
SELECT
MIN( tableC2.time - union_table2.time )
FROM
( SELECT
tableA.C_id,
tableA.time,
FROM
tableA
UNION ALL
SELECT
tableB.C_id,
tableB.time,
FROM
tableB
) AS union_table2,
tableC AS tableC2
WHERE
union_table2.C_id = tableC.id
AND tableC2.id = tableC.id

tableC.timeから見て、tableAとtableBのtimeのうち、一番近いものを一つだけ持ってくる
という操作です。

これを解決案1のようにしてしまうと、別々に持ってきたものをUNION ALLするので、
一つだけではなく二つ持ってきてしまうことになります。

解決は無理そうと思っていますが、もし可能だよ、という情報をご存じの方がいらっしゃいましたらご教示いただけますと幸いです。
また、不可能だよ、という情報ももしいただけますと、これ以上悩まなくて済むので同様にありがたいです。

よろしくお願い致します。


--
-------------------------------------------------------
◆ビービットはチームマイナス6%に参画しています◆
-------------------------------------------------------
株式会社ビービット 玉越 大輝
ユーザビリティ コンサルタント
beBit,Inc. Tamakoshi Hiroki hiroki.tamakoshi@xxxxx
--------------------------------------------------------

◆◆9月29日(月)より下記に移転いたしました◆◆

〒102-0071 東京都千代田区富士見2-14-37 FUJIMI EAST 1F
TEL: 03-5210-3891 / FAX: 03-5210-3895
URL: http://www.bebit.co.jp/
--------------------------------------------------------
◆◆◆お知らせ◆◆◆
・ユーザビリティ実践メモ(毎週月曜日更新)
http://www.bebit.co.jp/memo/

・ビービット書籍 『ユーザ中心ウェブサイト戦略』発売中
http://www.amazon.co.jp/gp/product/4797333529/


投稿者 xml-rpc : 2008年12月11日 19:49
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/79962
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。