JRA公式競馬データ配信サービス JRA-VAN Data Lab.

JRA-VAN DataLab.

競馬ソフト開発コーナー

JV-Dataの使い方あれこれ

一括表示 リストに戻る
タイトル意図的に、セットアップデータを複数回分ける方法
記事No5214
投稿日: 2023/09/18(Mon) 01:03
投稿者まさ
1986年から一気にすべてのデータを落とそうとすると、メモリリークが原因っぽ
いエラーが出るので、
セットアップデータを複数回分けて行う方法を行おうと考えております。

@「fromtime」に終了ポイント時刻を設定して、複数回行う方法、
A 終了ポイント時刻は設定しないで、「dataspec」を個々に指定する方法
があると思いますので、その2つのやり方について確認させてください。


@について、例えば1986-1995年、1996-2005年、2006年以降全て・・・の様に
行いたい場合、
@-1 「データ種別ID全て指定」と「19860101000000-19951299000000」にて
取得
@-2 「データ種別ID全て指定」と「19960101000000-20051299000000」にて
取得
@-3 「データ種別ID全て指定」と「20060101000000」にて取得

の形でよろしかったでしょうか?



Aについては、
『よくある質問』に、「dataspecを個々に指定するなど対象データを絞り、複
数回に分けてJVOpenを行う」と記載されていましたが、
dataspecよりさらに細かく、テーブル単位でデータベースに取り込もうと思っ
ております

A-1 「RACE」「19860101000000」を設定し、『レース詳細』を全件取り込む
A-2 「RACE」「19860101000000」を設定し、『馬毎レース情報』を全件取り
込む
A-3 「RACE」「19860101000000」を設定し、『払戻』を全件取り込む
A-4 「RACE」「19860101000000」を設定し、『票数1』を全件取り込む
  (一部省略)
A-1 「DIFN」「19860101000000」を設定し、『レース詳細』を全件取り込む
A-2 「DIFN」「19860101000000」を設定し、『馬毎レース情報』を全件取り
込む
A-3 「DIFN」「19860101000000」を設定し、『払戻』を全件取り込む
A-4 「DIFN」「19860101000000」を設定し、『票数1』を全件取り込む
  (一部省略)

 といった形でも大丈夫でしょうか?


 もしくは、テーブル単位がよくないのであれば、
A-1 「RACE」「19860101000000」を設定し、関係するテーブルを全件取り込

A-2 「DIFN」「19860101000000」を設定し、関係するテーブルを全件取り込

A-3 「BLDN」「19860101000000」を設定し、関係するテーブルを全件取り込

A-4 「MING」「19860101000000」を設定し、関係するテーブルを全件取り込


の様にしないと、ダメでしょうか?

タイトルRe: 意図的に、セットアップデータを複数回分ける方法
記事No5219
投稿日: 2023/09/18(Mon) 21:06
投稿者サメの餌
まささん、こんばんは。

セットアップ時にはちょっと気を付けた方が良い事が数点あります。
ちょっと公式資料の場所は忘れましたが、自分のソースから確認するとdataspe
cに指定するデータ種別IDによって、あっ、インターフェース仕様書に記述があ
りますね。TOKU、DIFN、HOSN、HOYU、COMMには"読み
出し終了ポイント時刻を指定することができません"となってます。

で、自分もここの常連さんに指導して頂きましたが、期間を区切ってセットア
ップデータを取り込んだ方が良いらしいので、自分のアプリでは1ヶ月に区切っ
て取り込んでます。つまり、1986年から現在までの取り込みを1ヶ月区切りで45
2回(37年x12+8)とかに分けている感じです。RACE、BLDN、MING、SNPN、SLOP、WO
OD、YSCHがこれに該当します。

フルセットアップには、自分はデータベースをSQLite3使ってますが、始めた当
初は随分時間が掛かってましたが、今はなんとか3時間程度で行えるまでになり
ました。こちらの方でアドバイス頂いた方達は1時間掛からないで行えたりして
る様です。JRA-VANの提供しているサンプルでも公式のアナウンスで時間が掛か
る的な事が書かれていたと思いますが、工夫は必要です。

上手く説明出来ているか疑問ですが、頑張ってください。

タイトルRe^2: 意図的に、セットアップデータを複数回分ける方法
記事No5220
投稿日: 2023/09/19(Tue) 08:50
投稿者まさ
サメの餌さん。こんにちは。


> りますね。TOKU、DIFN、HOSN、HOYU、COMMには"読み
> 出し終了ポイント時刻を指定することができません"となってます。


ご指摘の通り、その部分はありますね。
自分が書いた@の処理に該当しますが、範囲指定をしても、
『レース詳細』や『馬毎レース情報』は、範囲指定外のデータも
取り入れてしまうことになるかと思います。

範囲指定外のデータを削除しても整合性が取れるかは、
別途、『セットアップ完了済データにDELETE文を使用』に
あげておりました。


セットアップ方法の件、ご意見ありがとうございました。
1ヶ月単位で同じDBに反映する方法ですか?
@セットアップ(7月)
A8月通常データ取得(1週間)×4
Bセットアップ(8月)
の様に、通常データは取得していても、
再度、月ごとのセットアップを行うみたいな・・
上記の場合、@とAで整合性が取れていて、
Bを行わなくても大丈夫なはずなのですが・・


【追記】
「DIFN」のA-3、A-4の個所については、
該当テーブルに取り込んでいませんでしたので、
無視して頂ければと思います。
失礼いたしました。

タイトルRe^3: 意図的に、セットアップデータを複数回分ける方法
記事No5222
投稿日: 2023/09/19(Tue) 15:10
投稿者サメの餌
まささん、こんにちは。

説明があまり得意ではないので上手く伝わるか自信がありませんが...

セットアップ時には例えば、

dtStart = DateTime.Parse("1986/01/01 00:00:00");
dtEnd = DateTime.Parse("1986/02/01 00:00:00");

としておいて、

strFromTime = dtStart.ToString("yyyyMMddHHmmss") + "-&qu
ot; + dtEnd.ToString("yyyyMMddHHmmss");

として

iOption = 4;

で僕は回してます。これをdataspecに"RACE"、"BLDN"、&
quot;MING"、"SNPN"、"SLOP"、"WOOD"、&
quot;YSCH"と個々に指定して同一ループで1ヶ月ずつ、つまり、1986年1月
分としてこの7種類のdataspec個々に取得して日付を次の月にという感じのルー
プです。で、ループ最後の終了日が例えば今月でしたら2023年9月〜10月の時に
は開始日のみの指定で行いループ終了。

その後で終了日の指定出来ない他のdataspecの"DIFN"、"HOSN&
quot;、"HOYU"、"COMM"を行います。

で、セットアップは完了なので、この後の運用は

iOption = 1;

で毎週金曜日、土曜日にそれぞれ更新とまあ、月曜日にも更新したり、しなく
ても金曜日に一気に更新されます。この更新で、lastfiletimestampを開始日に
終了日をDateTime.Nowとかにして終了日指定可能dataspecに指定して、それ以外
は開始日のみで。

指定日以外が取得されてデータの整合性が取れるかどうかとかほぼ気にしてま
せん。個々のデータがデータ区分が削除になっている時のみ削除してます。

説明下手で申し訳ないです。

タイトルRe^4: 意図的に、セットアップデータを複数回分ける方法
記事No5226
投稿日: 2023/09/20(Wed) 15:05
投稿者まさ
サメの餌さん。こんにちは。


> で僕は回してます。これをdataspecに"RACE"、"BLDN&quo
t;、&
> quot;MING"、"SNPN"、"SLOP"、"WOOD&qu
ot;、&
> quot;YSCH"と個々に指定して同一ループで1ヶ月ずつ、つまり、1986
年1月
> 分としてこの7種類のdataspec個々に取得して日付を次の月にという感じ
のルー
> プです。で、ループ最後の終了日が例えば今月でしたら2023年9月〜10月
の時に
> は開始日のみの指定で行いループ終了。
>
> その後で終了日の指定出来ない他のdataspecの"DIFN"、"
HOSN&
> quot;、"HOYU"、"COMM"を行います。
>
> で、セットアップは完了なので、この後の運用は
>
> iOption = 1;

終了日時を指定できるデータ種別IDであれば、
各々のデータ種別IDを、一か月単位で何十年も回し、
終了日時を指定できないデータ種別IDを、
最後に一回実行する感じですね。

指定できないデータ種別IDは、別途速度を試しましたが、
「TOKUDIFFHOSEHOYUCOMM」でまとめても
問題ない速度でしたので、私はまとめて実行にしようかと思います。

それが3時間くらいでできるのであれば、
別段バックアップは不要かもですね。
2日かかるなら、バックアップから戻したいですが・・・

タイトルRe^2: 意図的に、セットアップデータを複数回分ける方法
記事No5221
投稿日: 2023/09/19(Tue) 09:02
投稿者まさ
> フルセットアップには、自分はデータベースをSQLite3使ってますが、始め
た当
> 初は随分時間が掛かってましたが、今はなんとか3時間程度で行えるまで
になり
> ました。こちらの方でアドバイス頂いた方達は1時間掛からないで行えた
りして
> る様です。


とてもじゃないですが、30年のセットアップがその時間では
到底厳しい状況です。
現在で、2-3日かかる勢いです。

多分、データ種別IDは1つに絞ってないからだと思いますが
現在、フルセットアップ中なので、終わったらデータ種別1個で
試そうとは思います

タイトルC#でのメモリ解放関連
記事No5223
投稿日: 2023/09/20(Wed) 07:02
投稿者サメの餌
まささん、おはようございます。

> 1986年から一気にすべてのデータを落とそうとすると、メモリリークが原
因っぽ

まささんはC#でしたっけ? VB.NETでは問題ないって事だったかと思いますが、C
#の場合はJVGetsでの読込でのバッファの開放が面倒で、ここの「JV-Link 質問
箱」で過去ログにあるんですが、過去ログで"P 00006"を選択すると2
ページ目辺りにNo.6853の「C#でのメモリ解放」という たかひろさん が立て
たスレッドがありますので参考にするとよろしいと思います。
C#でもJVGetsでもなかったら見る必要はないかとは思いますか、ここにも1ヶ月
毎に区切るとセットアップ時間が短縮される感じの話もあります。

自分の方法はまだまだな感じで更に効率よく出来るとは思いますが、上の過去
ログのたかひろさんが確かソースへのリンクも張ってたかと思いますが、それも
参考になるかと。"RACE"に対して期間指定して「レース詳細」取得し
て、更に別のJVOpenで"RACE"して今度は「馬毎レース情報」的に行う
と無駄にJVOpenする事になるかもです。"RACE"で飛んでくる13種類で
自分の必要ない情報だったらJVSkipして必要なものはDB登録する方が効率は良く
なるんじゃないかと。

まささんはMySQLでしたっけ?ちょっと触った事がないのでイメージが出来ませ
んが、SQLiteではDB接続してコマンド準備してSQL実行して接続切るの繰り返し
が基本なんですが(実際にはトランザクションとかも入れて)、この処理も自分は
最初毎月のdataspec毎にしてたんですが、今はDB接続をセットアップ開始時に1
回のみで、セットアップ完了してようやくDB接続解除してます。コマンドもセッ
トアップで使うであろう物全てを準備しておいて、セットアップ中は使い回す。
等々の工夫で無駄な処理を省いて時間短縮しました。
これが正攻法かは分かりませんが極力無駄を省く様に、更にJRA-VAN提供の構造
体使うのも止めてます。これすると確かにソースコード的には見た目も分かりや
すい感じではありますが、JVGetsからのバッファから直接的にDBコマンドに値を
設定した方が高速化出来ました。

作り始めた時には何度もセットアップしなきゃならず、しかも14時間とか掛か
ってましたので、バグつぶしてまた待ってが苦痛でした。あっ、僕の場合ですが
、元々VB.NETでEntityFrameworkのコードファーストでDB定義して的なスタート
で14時間どころかまささんの3日間以上だった感じです。SQLiteはEntityFramewo
rkでのアクセスではトランザクションが微妙で、ちょっと正確には把握してませ
んが余分にトランザクションが入っているのかそもそも入ってないのかデータ登
録が激遅だったんです。なので、EntityFrameworkでのコードは全て無駄で書き
直し。

後は「ループ処理にはApplication.DoEvent()」的にWindowsアプリのコーディ
ングしてたんですが、このDoEventがかなり重くて、これを減らす事で随分早く
なりました。

ちょっと長くなりましたが、参考になれば幸いです。

タイトルRe: C#でのメモリ解放関連
記事No5224
投稿日: 2023/09/20(Wed) 14:36
投稿者まさ
サメの餌さん。こんにちは。

色々記載して頂きまして、ありがとうございます。


> まささんはC#でしたっけ? VB.NETでは問題ないって事だったかと思います
が、

環境はVB.NETでございます。
比較対象として、everydb2を使ってみましたが、
メモリリークが原因と思われるエラーが出ました。
なお、everydb2は、終了日時を指定できなかったもので・・


> 参考になるかと。"RACE"に対して期間指定して「レース詳細」
取得し
> て、更に別のJVOpenで"RACE"して今度は「馬毎レース情報」的
に行う
> と無駄にJVOpenする事になるかもです。"RACE"で飛んでくる13
種類で
> 自分の必要ない情報だったらJVSkipして必要なものはDB登録する方が効率
は良く
> なるんじゃないかと。


もしかしたら、同じ条件のJVOpenで、スピードが速くなるかも
とは思ったのですが、無駄なJVOpenになるっぽいですね。



> 最初毎月のdataspec毎にしてたんですが、今はDB接続をセットアップ開始
時に1
> 回のみで、セットアップ完了してようやくDB接続解除してます。


これは同じ考え方ですね。
毎月の分を30年も行うのであれば、接続切断は一回でよいかなと
思っております。

タイトルRe: C#でのメモリ解放関連
記事No5227
投稿日: 2023/09/20(Wed) 15:09
投稿者まさ
サメの餌さん。こんにちは。

「JVGets」という文言があったので、確認してみました。
サンプルが「JVRead」だったので、そっちを使うものかと・・

「インターフェース仕様書」を見てみましたが、
パフォーマンスが上がるみたいなので、
「JVGets」を使った方がよさそうですね・・

タイトルRe: 意図的に、セットアップデータを複数回分ける方法
記事No5225
投稿日: 2023/09/20(Wed) 14:53
投稿者まさ
試しに、DB登録を無しにして、純粋なJVReadの時間を測定しました。

「RACEBLODMINGSNAPSLOPWOOD」を指定して、
一か月で2秒、1年で47秒でしたので、
データ種別IDをつなげるなら、このあたりが限度かと思います。
なお、10年では1万件で143秒かかり、
一千万レコード近くあるので、読み込むだけで40時間かかります。

処理が軽い「BLOD」「MING」「SNAP」「SLOP」「WOOD」は、
1986年から全データを単体で行っても、合計12分で終わりますが、
「BLODMINGSNAPSLOPWOOD」にしたら、多分10時間以上かかります。

「TOKUDIFFHOSEHOYUCOMM」であれば、終了日時は指定できませんが
1986年から全データでも、4秒でした。

見る限り、データ種別IDをつなげるのが一番遅くなり、
次に遅くなるのが、期間を延ばす事といった感じですね。

やっぱり、一つ一つを一か月で回すのがよいかなと思いました。

タイトル素で回した場合
記事No5229
投稿日: 2023/09/20(Wed) 17:30
投稿者サメの餌
まささん、こんばんは。

今日は仕事休みでしたので、ちょっとだけ...

自分のアプリにはテキスト出力機能とCSV出力機能を一応実装してるんですが、
これ、自分では使う事が殆どないのでデバックが未完全だとは思うんですが、フ
ルセットアップしてみました。

テキスト出力 → 8分弱
CSV出力 → 15分弱

でした。テキスト出力は単にJVGetsで読込んだバッファをテキスト出力してる
ので、ほぼ素なJVGetsの処理時間に近いんだと思います。CSV出力は、一応読み
込んだバッファを項目毎に切り分けている処理が入ってますので、その違いと思
って頂いてよろしいかと思います。フルセットアップっとは、1986年〜現在まで
のデータの取得です。あっ、基本的な部分はdataspecは1つずつの1ヶ月毎の取得
です。

へぼなコーディングでの話で参考にすらならないかもですが...

タイトルRe: 素で回した場合
記事No5232
投稿日: 2023/09/22(Fri) 19:02
投稿者まさ
サメの餌さん
こんばんは


> フルセットアップしてみました。
>
> テキスト出力 → 8分弱
> CSV出力 → 15分弱

速いですねー
参考になります。ありがとうございました。

後でプログラムを改変して試してみたいと思います。
一か月、1項目が正解っぽいですね。

ウィンドウを閉じる