[前][次][番号順一覧][スレッド一覧]

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]