mysql:15624
From: HIRATSUKA Sadao <HIRATSUKA Sadao <hiratsuka.sadao@xxxxxxxxxx>>
Date: Wed, 31 Aug 2011 12:33:06 +0900
Subject: [mysql 15624] Re: mysql 5.5.9でのset names sjisで性能低下
こんにちは、平塚です。 On Tue, 30 Aug 2011 20:29:54 +0900 (LMT) Etsuo SUMIYA <sumiya-e@xxxxxxxxxx> wrote: > "set names sjis"を実行すると、t2の > rowsが10となり、indexがきかず、全スキャンかかってしまうようです。 いただいたテストケースは MySQL 5.5.11で再現して、MySQL 5.5.12だと再現しませんでした。 たぶん↓これです。 http://bugs.mysql.com/bug.php?id=60625 ただそれとは別に 最新のMySQL 5.5.15でも再現するケースを作れたので、バグ報告してみました。 http://bugs.mysql.com/bug.php?id=62307 仕組みとしては、tm = '20:01'という検索条件を CONVERT(tm USING SJIS sjis) = '20:01' に変換するわりと残念なロジックがMySQL 5.5から入っていて、 これの発動条件の一つがcharacter_set_connection = ucs2あるいはsjis となっているようです。 ucs2のためにはこのロジックがどうしても必要なようですが、 sjisは巻き添えを喰らった感があります。 このロジックが発動するとファンクションが挟まるため インデックスが使われなくなってしまいます。 この挙動はEXPLAINではなくEXPLAIN EXTENDEDコマンドを使って、 直後にSHOW WARNINGをすると確認できます。 MySQL 5.5.12以降では、tm列をt1から持ってくる過程で 運よくロジックの発動を回避できているようです。 ・対処案1 MySQL 5.5.9から変更できない場合、 SELECT t2.name, t1.tm, t2.v FROM t2, t1 WHERE t2.name = 'n1' AND t2.tm = CAST(t1.tm AS UNSIGNED) AND DATE(t1.dt) = '2011-08-30'; とすると期待したSQL実行計画になります。 おすすめはしませんが…。 ・対処案2 sjisではなくて例えばcp932にすれば直ります。 ・対処案3 MySQL 5.5.12以上にすればとりあえずテストケースのクエリは良くなります。 ただ、t2を単独でSELECTすると発動してしまいます。 SELECT * FROM t2 WHERE name = 'n1' AND tm = '20:01'; これに対しては SELECT * FROM t2 WHERE name = 'n1' AND tm = TIME('20:01'); とすると直ります。ちなみにMySQL 5.5.11では SELECT * FROM t2 WHERE name = 'n1' AND tm = CAST(TIME('20:01') AS UNSIGNED); とまでする必要があります。 ・対処案4 Bug#62307がVerifyされて直るまで待ちます。 よろしくお願いいたします。 -- 平塚貞夫 hiratsuka.sadao@xxxxxxxxxx
15623 2011-08-30 20:29 [Etsuo SUMIYA <sumiya] mysql 5.5.9でのset names sjisで性能低下 -> 15624 2011-08-31 12:33 ┗[HIRATSUKA Sadao <hir] 15625 2011-08-31 18:27 ┗[Etsuo SUMIYA <sumiya] 15626 2011-09-01 09:50 ┗[HIRATSUKA Sadao <hir]