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

mysql:16329

From: ユメ吉 <ユメ吉 <yume_tana@xxxxxxxxxx>>
Date: Sun, 1 May 2016 11:50:14 +0900 (JST)
Subject: [mysql 16329] Re: [mysql 16328] Re: [mysql 16327] Re: [mysql 16326] Re: [mysql 16325] Re: [mysql 16324] 処理速度が遅い

ゆめ吉です。

昨日は不在で、返事が遅れました。

みなさんからのアドバイスから判断して、あまりおかしくなさそうです。
MySQLは高速と聞いていたので、もしかしておかしいのかな思っていました。

確かにデータは変わらないので毎日追加するほうが得策ですね!

宮田さんからのプロシージャを参考に考えて見ます。

今後もよろしくお願いします。


----- Original Message -----
>From: Masaki Miyata <catlover@xxxxxxxxxx>
>To: ml@xxxxxxxxxx 
>Date: 2016/5/1, Sun 09:25
>Subject: [mysql 16328] Re: [mysql 16327] Re: [mysql 16326] Re: [mysql 16325] Re: [mysql 16324] 処理速度が遅い
>  
>
>こんにちは。宮田です。
>
>
>> > avg(case when B.日付 >= date_add(A.日付,interval -7 day)  then B.数値1  else null end ) as "7d_1_HEIKIN" ,
>> と、A.日付で終端されてないので、4/28のレコードを固定化しても4/29以降の値を含んで、固定化難しいんじゃないかなとか思ってました(間違い?)
>
>
>where B.hizuke between date_add(A.hizuke, interval -365 day) and A.hizuke
>
>
>上記のJOIN条件にて、between で範囲指定してあるので、
>A.hizuke 以降は含まれないようになっていますね。
>
>
>
>
>宮田 昌紀
>catlover@xxxxxxxxxx 
>
>2016年4月30日 14:10 yoku ts. <yoku0825@xxxxxxxxxx>:
>
>こんにちは、yoku0825といいます。 
>>これ、元の式が 
>>> avg(case when B.日付 >= date_add(A.日付,interval -7 day)  then B.数値1 else null end ) as "7d_1_HEIKIN" , 
>>と、A.日付で終端されてないので、4/28のレコードを固定化しても4/29以降の値を含んで、固定化難しいんじゃないかなとか思ってました(間違い?) 
>>求められている回答とは違うんですが、InfiniDBでやったらまともな処理速度が出そうだったので、Window関数を持っている他のRDBMSが良いんじゃないかなと思います。
>> 
>>yoku0825, 
>> 
>>2016/04/30 10:42 "Masaki Miyata" <catlover@xxxxxxxxxx>:
>>>
>>> こんにちは。
>>> 宮田と申します。
>>>
>>> 頭の体操にちょっとやってみました。
>>>
>>> そのSQLで求めるなら、
>>> 最低限、「keycode,hizuke」の複合インデックスが必要ですね。
>>>
>>> 2013/1/1 から日次でサンプルデータを作って試してみました。
>>> WindowsのノートPC、Core i5-4200Uメモリ 8GB、MySQLのメモリーチューニング無しの状態で、
>>> 1日分で5〜10秒くらい。
>>>
>>> まぁ、自己結合で日付を最大1年とはいえクロス結合するので、
>>> 1日分で73万件(2000*365)処理することになるので、妥当じゃないでしょうか。
>>>
>>> 過去分が変わらないのであれば、1日分をサマリーテーブルに入れていけばよいです。
>>>
>>> -- ■日次のサマリ作成
>>> insert into tb_sum
>>>  (hizuke, keycode,
>>>  7d_1_HEIKIN, 7d_2_HEIKIN, 31d_1_HEIKIN, 31d_2_HEIKIN,
>>>  180d_1_HEIKIN, 180d_2_HEIKIN, 365d_1_HEIKIN, 365d_2_HEIKIN)
>>> select
>>>  A.hizuke,
>>>  A.keycode,
>>>  avg(case when B.hizuke >= date_add(A.hizuke, interval  -7 day) then B.num1 else null end ) as  '7d_1_HEIKIN',
>>>  avg(case when B.hizuke >= date_add(A.hizuke, interval  -7 day) then B.num2 else null end ) as  '7d_2_HEIKIN',
>>>  avg(case when B.hizuke >= date_add(A.hizuke, interval -31 day) then B.num1 else null end ) as '31d_1_HEIKIN',
>>>  avg(case when B.hizuke >= date_add(A.hizuke, interval -31 day) then B.num2 else null end ) as '31d_2_HEIKIN',
>>>  avg(case when B.hizuke >= date_add(A.hizuke, interval -150 day) then B.num1 else null end ) as '180d_1_HEIKIN',
>>>  avg(case when B.hizuke >= date_add(A.hizuke, interval -150 day) then B.num2 else null end ) as '180d_2_HEIKIN',
>>>  avg(case when B.hizuke >= date_add(A.hizuke, interval -365 day) then B.num1 else null end ) as '365d_1_HEIKIN',
>>>  avg(case when B.hizuke >= date_add(A.hizuke, interval -365 day) then B.num2 else null end ) as '365d_2_HEIKIN'
>>>  from tb A, tb B
>>> where A.keycode = B.keycode
>>>  and A.hizuke = '2016-04-29'
>>>  and B.hizuke between date_add(A.hizuke, interval -365 day) and A.hizuke
>>> group by A.keycode, A.hizuke;
>>>
>>> -- ■テーブルやテストデータ作成のプロシージャなど
>>>
>>> -- phpMyAdmin SQL Dump
>>> -- version 4.2.7.1
>>> -- http://www.phpmyadmin.net/
>>> --
>>> -- サーバのバージョン: 5.6.20
>>> -- PHP Version: 5.5.15
>>>
>>> SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
>>> SET time_zone = "+00:00";
>>>
>>> --
>>> -- Database: 'test1'
>>> --
>>>
>>> DELIMITER $$
>>> --
>>> -- プロシージャ
>>> --
>>> CREATE DEFINER=`root`@`localhost` PROCEDURE `ins`()
>>>   NO SQL
>>> BEGIN
>>> START TRANSACTION;
>>> SET @k = 1;
>>> SET @d = '2013-01-01';
>>>
>>> WHILE '2016-04-29' >= @d DO
>>>  WHILE 2001 > @k DO
>>>   insert into tb (`keycode`,`hizuke`,`num1`,`num2`)
>>>    values( @k, @d, CEIL(RAND() * 1000), CEIL(RAND() * 2000));
>>>   SET @k = @k +1;
>>>  END WHILE;
>>>  SET @k = 1;
>>>  SET @d = date_add(@d, interval +1 day);
>>> END WHILE;
>>> COMMIT;
>>> END$$
>>>
>>> DELIMITER ;
>>>
>>> -- --------------------------------------------------------
>>>
>>> --
>>> -- テーブルの構造 'tb'
>>> --
>>>
>>> CREATE TABLE IF NOT EXISTS tb (
>>> id int(10) unsigned NOT NULL,
>>>  keycode int(10) unsigned NOT NULL,
>>>  hizuke date NOT NULL,
>>>  num1 int(10) unsigned NOT NULL,
>>>  num2 int(10) unsigned NOT NULL
>>> ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2778524 ;
>>>
>>> -- --------------------------------------------------------
>>>
>>> --
>>> -- テーブルの構造 'tb_sum'
>>> --
>>>
>>> CREATE TABLE IF NOT EXISTS tb_sum (
>>> id int(10) unsigned NOT NULL,
>>>  keycode int(10) unsigned NOT NULL,
>>>  hizuke date NOT NULL,
>>>  7d_1_HEIKIN double unsigned NOT NULL,
>>>  7d_2_HEIKIN double unsigned NOT NULL,
>>>  31d_1_HEIKIN double unsigned NOT NULL,
>>>  31d_2_HEIKIN double unsigned NOT NULL,
>>>  180d_1_HEIKIN double unsigned NOT NULL,
>>>  180d_2_HEIKIN double unsigned NOT NULL,
>>>  365d_1_HEIKIN double unsigned NOT NULL,
>>>  365d_2_HEIKIN double unsigned NOT NULL
>>> ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2048 ;
>>>
>>> --
>>> -- Indexes for dumped tables
>>> --
>>>
>>> --
>>> -- Indexes for table tb
>>> --
>>> ALTER TABLE tb
>>> ADD PRIMARY KEY (keycode,hizuke), ADD UNIQUE KEY id (id), ADD UNIQUE KEY uq (hizuke,keycode);
>>>
>>> --
>>> -- Indexes for table tb_sum
>>> --
>>> ALTER TABLE tb_sum
>>> ADD PRIMARY KEY (keycode,hizuke), ADD UNIQUE KEY id (id), ADD UNIQUE KEY uq (hizuke,keycode);
>>>
>>> --
>>> -- AUTO_INCREMENT for dumped tables
>>> --
>>>
>>> --
>>> -- AUTO_INCREMENT for table tb
>>> --
>>> ALTER TABLE tb
>>> MODIFY id int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=2778524;
>>> --
>>> -- AUTO_INCREMENT for table tb_sum
>>> --
>>> ALTER TABLE tb_sum
>>> MODIFY id int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=2048;
>>>
>>>
>>>
>>> 宮田 昌紀
>>> catlover@xxxxxxxxxx
>>>
>>> 2016年4月30日 0:13 HIRATSUKA Sadao <sh2@xxxxxxxxxx>:
>>>
>>>> ユメ吉さん
>>>> こんばんは、平塚といいます。
>>>>
>>>> なんとなくですが、株式などの市場データでしょうか。
>>>> 数値1が最高値、数値2が最安値、それで直近1週間、1か月、
>>>> 半年(180日ではなくて?)、1年の移動平均を出したい、
>>>> ということでイメージ合うでしょうか。
>>>>
>>>> この、移動平均をかなりの力技で計算しているので、
>>>> MySQL的につらいことになっていると思われます。
>>>>
>>>> EXPLAINを見てインデックスを追加するというMySQLの技術力よりも、
>>>> RDBMSで移動平均をどうやって計算すればよいのだろう、
>>>> といったところに工夫が求められる感じです。
>>>>
>>>> それから、
>>>> 過去にさかのぼって数値1、数値2が変化することはありますか?
>>>> もし市場データでしたら過去のデータは変わらないですよね。
>>>>
>>>> 4か月分の計算に96分かかったのことですが、前日までのデータは
>>>> 1回計算すればそれを記録しておけばよい、といったことはないでしょうか。
>>>>
>>>> 昨日までのデータがすでに計算してあるのならば、
>>>> 今日の分を9.6秒かけて計算して、末尾に追加するだけ、
>>>> といった運用ができるかもしれませんね。
>>>>
>>>> とはいえMySQLの技術力でどうにかねじ伏せられるかどうかについては
>>>> 思いついたらメールしてみようと思います。
>>>> #今日は思いつきませんでした(^^;
>>>>
>>>> 2016年4月29日 23:28 ユメ吉 <yume_tana@xxxxxxxxxx>:
>>>> > MySQLをはじめて1ヶ月の初心者です。以前、他のRDBを少しかじった程度ですが
>>>> > 本格的にものにしようと勉強中です。
>>>> > ところが、MySQLの処理速度が遅いので困惑しており、メールをしたところです。
>>>> >
>>>> > テーブルは日付、 keycode、数値1、数値2と簡単ですが、データ量は毎日取込んでおりで
>>>> > keycodeが2000種程になるので今では200万件を超えております。
>>>> > 今回MySQLに移植しなおして、ためしにselect * from テーブル名(tb)de開けたところ3.2秒かかりました。
>>>> > まだインデックスは付けていませんが、 keycodeだけ付けましたが2.2秒とあまり変わりません。
>>>> > その時、EXPLAINを見ましたが type = ALL Key=NULL Extra = NULL になっていました。
>>>> > 今回は自己結合を使って日付、 keycodeごとに1週間分、1か月分、半年分、一年分の平均を算出していきたく
>>>> > クエリーを作りました。 A.日付 >= '2016-04-29' にして直近だけで9.6秒かかりました。
>>>> > ちなみに今年から(A.日付 >= '2016-01-01' )では 96分かかっていました。本当は2年分程を5〜6分以内に
>>>> > できないか思っております。
>>>> > この時の条件は 日付とkeycodeを単独でインデックスを作りました。
>>>> > explain は tb A type = range ,key=日付  ,extra =Using index condition; Using
>>>> > MRR; Using temporary; Using filesort
>>>> >      tb B type = ref ,key=keycode ,extra =Using where
>>>> > MYSQLのVer=5.7 モメリー=4G  OS=WIN7pro
>>>> > explainは初めてで良くわかりませんが、速度アップのためのご指導頂けないでしょうか。
>>>> > ***************************************************************
>>>> > select
>>>> >  A.hizuke    as "HIZUKE" ,
>>>> >  A.keycode    as "KEYCODE",
>>>> > avg(case when B.日付 >= date_add(A.日付,interval -7 day)  then B.数値1 else
>>>> > null end ) as "7d_1_HEIKIN" ,
>>>> > avg(case when B.日付 >= date_add(A.日付,interval -7 day)  then B.数値2 else
>>>> > null end ) as "7d_2_HEIKIN" ,
>>>> > avg(case when B.日付 >= date_add(A.日付,interval -31 day) then B.数値1 else
>>>> > null end ) as "31d_1_HEIKIN" ,
>>>> > avg(case when B.日付 >= date_add(A.日付,interval -31 day) then B.数値2 else
>>>> > null end ) as "31d_2_HEIKIN" ,
>>>> > avg(case when B.日付 >= date_add(A.日付,interval -150 day) then B.数値1 else
>>>> > null end ) as "180d_1_HEIKIN" ,
>>>> > avg(case when B.日付 >= date_add(A.日付,interval -150 day) then B.数値2 else
>>>> > null end ) as "180d_2_HEIKIN" ,
>>>> > avg(case when B.日付 >= date_add(A.日付,interval -365 day) then B.数値1
>>>> > else null end ) as "365d_1_HEIKIN" ,
>>>> > avg(case when B.日付 >= date_add(A.日付,interval -365 day) then B.数値2
>>>> > else null end ) as "365d_2_HEIKIN" ,
>>>> > from tb A , tb B
>>>> >
>>>> > where A.keycode = B.keycode
>>>> > and  A.日付 >= '2016-04-29'
>>>> > and  B.日付 between  date_add(A.日付,interval -365 day) and A.日付
>>>> >
>>>> > group by A.keycode ,A.日付
>>>> >
>>>> > ******************************************************************
>>>>
>>>>
>>>>
>>>> --
>>>> 平塚貞夫 <sh2@xxxxxxxxxx>
>>>
>>>
>> 
> 
>
>

添付ファイル

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

   @ 16324 2016-04-29 23:28 [ユメ吉 <yume_tana@xx] 処理速度が遅い                          
     16325 2016-04-30 00:13 ┗[HIRATSUKA Sadao <sh2] Re: [mysql 16324] 処理速度が遅い      
   @ 16326 2016-04-30 10:39  ┗[Masaki Miyata <catlo] Re: [mysql 16325] Re: [mysql 16324] 処理速度が遅い
   @ 16327 2016-04-30 14:10   ┗["yoku ts." <yoku0825] Re: [mysql 16326] Re: [mysql 16325] Re: [mysql 16324] 処理速度が遅い
   @ 16328 2016-05-01 09:25    ┗[Masaki Miyata <catlo] Re: [mysql 16327] Re: [mysql 16326] Re: [mysql 16325] Re: [mysql 16324] 処理速度が遅い
-> @ 16329 2016-05-01 11:50     ┗[ユメ吉 <yume_tana@xx] Re: [mysql 16328] Re: [mysql 16327] Re: [mysql 16326] Re: [mysql 16325] Re: [mysql 16324] 処理速度が遅い