日曜日の静寂

静かに。そして、強く生きていきたい。一口馬主とFXと。

爆速SQL~競馬予想プログラム~

IT

予想アルゴリズムは・・・

そんなに難しいことを考えているわけではありません。
出走馬の過去5Rを点数化し、競走馬の能力指数のようなものを算出し、順位付けします。
これをもとに、一定の買い方で馬券を買うというものを作ろうと考えました。

能力指数的なものでいえば、JRA-VANのデータマイニングという機能があります。
まずは、それを使って順位が自分のソフトで出力できるか試してみました。
1日単位で順位データをCSVに出力できれば、自動購入ソフトに取り込めますし、それを使えばバックテスト(過去のレースから成績を確認)できるので、能力指数の精度を高められます。
データマイニングを指数として作成するのは1日当たり10秒もかからず算出できました。
なので、これはいけるな…と。

独自指数を作るために過去レースデータを取り込もうとすると…

ここまではよかったんですよね。。。
各レースの出走馬の直近5走のレースデータを呼び出して、点数付けする。
これをまとめて競走馬に順位をつけていけばはいOK

の、はずでした。
まずは直近5走のデータを呼び出すプログラムを作って、ばっと一覧を出そうと試みたところ、ここでタイムアウト発生。
PHPのタイムアウトを伸ばしてみた。180秒=3分。
これで出力できなきゃお話になんない。
しかし、それでもタイムアウト。これは困った。
1日で3分も10分もかかるようでは、過去1年間のデータを出力していったん取り込んで検証、、、なんてことも全くできないじゃないか。これは困った。

DBのチューニング

どう見ても明らかにDB、SQL文の問題に見える。
何が悪いのかも今のところ見えていない。

しかしセオリー通りチューニングを行いながら、少しずつでもパフォーマンスアップを狙うしかないだろう。

インデックス

DBパフォーマンスアップの第一歩はインデックスだ。
Where句やorderbyで使うカラムにインデックスをかけるかかけないかでパフォーマンスが大きく変わってくる。
面倒であまりやらないのだが、はやり数百万件という馬毎のレース情報はインデックスをかけていかないと早くならないだろう。
今回は今Where句やOrderByで使っているカラムをすべてインデックスをかけた。

しかしながら、パフォーマンスは上がらない。
そこで、古馬重賞レースに出走予定の競走馬1頭を狙い打ってSQL文を実行してみたところ、0.01秒程度で過去5レースのデータを算出できた。
あれれ、、この秒数なら1日の全出走馬の過去5Rのデータを出力するくらいなら、10秒もかからない気がするが。。。
なぜだ。。。

原因がわかってきた。
パフォーマンス向上のために、Limitをかけているのだが、単純にLimit 0,5としているのだが、競走実績が5件に満たない馬がいる。
例えば新馬は競走実績が0件だし、5走していない競走馬なんて死ぬほどいるだろう。
新馬でこのクエリを発行すると30秒近くかかってデータなしとなる。
そりゃ、8頭立ての新馬戦があればもうその時点で4~5分近くかかるんだから1Rすらも結果を出せないだろう。

なるほど分かった。要は件数か。

でもどうしたら…

理由は分かったのだが、だからってどうやってこの馬は競走実績が0~4戦しかありませんよっていうのを認識するのか。これがまた問題だ。
SQL側だけでできないのならPHP側で何かできないか考えてみた。
そうか。
mysqli_num_rowsで、件数を見てみればいいのか!
と、さっそくレコード件数を出力する関数でSQLをたたいてみたが、、、
わかる人は分かるが、SQL文が変わったわけではないので、結局遅い。。。
だめだ、、、わかんない。。。

一度冷静になろう。
どうすればいいか考えながらコードをきれいにしよう。
クウォート【'】をはしょった個所がいくつかあったから書くべきところはクウォートをちゃんと書いておこう。
そして、SQLを一度シンプルにしよう。
データの区分コードがあって、成績発表の区分と出馬表発表の区分がある。
今回のレースの予想をするためには過去レースが必要なので、成績発表済みのレースだけに絞りたくてこの区分で成績発表済みのレースに絞っていたのだが、これはLimitで新しい順に並べた後に、Limit 1,5とすることで、最新レースの1個前からという処理ができるから一度レース区分での絞り込みをなくそう。
競走馬コードのみで絞ってとりあえず5件出力するようにしよう。

あれ?なんか早くなった気がする、、、
いやまて、これは重賞出走古馬だから、さっきも早かった。。。さっきより少し早いけど、それはMySQLのキャッシュかもしれないしね。。。出走経験のない新馬で一回やってみよう。さっきは30秒だからね。。。

あれ、、、0.01秒で出力したな。。。
あれ、、、何が違ったんだ???

まとめ~爆速クエリを作るために必要なこと~

さて、前文までで行ったことはすべて書きましたが、その後、削除したデータの区分の絞り込みも、Limitも完全に復活させましたが、1日分のデータを呼び出すのに2秒とかからなくなりました。
どこで早くなったかわかりますか?

Share / Subscribe
Facebook Likes
Tweets
Hatena Bookmarks

フォロー・チャンネル登録よろしくお願いします

おすすめソフト

Emotetをいち早く検知!ESETのご紹介

静寂さん
ウィルスソフトならESETをお奨めするよ!
美和
え?どうしてですか?
静寂さん
2022年初頭に日本で大流行したEmotet。
このEmotetに対していち早く対応できたのがESETだね。
ソフトとしても軽いし検知率高いしそれでいて安価だしね。
日本のキャノンが制作しているっていうのもいいよね。
美和
ウィルスソフトにお困りの方にはお勧めですね!

MS-Officeとの高い位互換性!KINGSOFT-Officeのご紹介

静寂さん
サブ機PCや、プライベートPCなんかに入れておくと重宝すると思うんだ。
美和
MS-Officeとの互換性も高いみたいですね。
静寂さん
会社ではマクロも組んでいて、MS-Officeじゃないとだめかもしれないけど、家庭でのちょっとした競馬の収支や家計簿、住所録程度の仕様ならKingSoftのOfficeでも十分じゃないかね?
美和
ちょっとした計算資料作るには向いているかもしれませんね!