中央競馬の予想や購入したもののメモなどを書いて行こうかと。まあ、個人的なメモ的なブログです。
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
業務ではほぼDB関連の仕事してないので、ほぼというのは全くではないけど、管理者としては関わってないけど、DB絡みのプロジェクトは経験有り、他の開発者とはDBとは的な話はした事はある。ってか、多分偉そうな事を言った気がする。学生時代の記憶からだと思うが、DBとは的な知識からリレーショナルDBとインデックスシーケンシャルなデータファイル管理とかの話だったかもだけど、間違ってはなかったとは思うが、偉そうに言えるレベルではなかったかも^^;
なんにしても、SQLite3にデータ登録は納得がいくレベルで処理出来る所まで来てると思うけど、いやね、実際にはまだ少し手を抜いてるから早いだけな気もしてますが、そこは置いておいて、今回は登録済んだので、そのデータの利用な部分なんですが、これがまた当初はEntity Frameworkの遅さがって事だったんですが、EF無でも遅いのは...
もう、ここ数日色々グーグル先生にも問い合わせましたが的確な回答は得られず、随分色々と試しましたが、現時点の自分の力量ではここは放置が吉と判断して、別処理の開発に進む事にしました。まあ、その際、ちょっとだけごまかしじゃないけど、見た目としての逃げでForm_Loadイベントで全てこなすと表示されるまで延々と何も起きないのを待つのはユーザーには問題かな~っと時間掛かる処理をForm_Shownイベントに移動する事で画面上では少し変化した状態で固まる(笑)感じにしてみた。これなら何となくWindowsかSystemが遅いのかな~って感じにも見えなくはないので苦肉の策です。余裕が出来たら改善してみる努力はしようかな~っと^^ いやね、リッチにSQLiteのDBファイルをSSDに丸ごと乗せればもう少しレスポンスも早いだろうとか、ねぇ~(笑) 自分では絶対にSSDの寿命縮めるので試しませんけど^^;
少し考えてたのですが、今回自分がやっている事はあくまでEntity FrameworkでSQLiteを扱うって事なんですが、今回のコードファーストやり始め、SQL Server Expressに対しては本当に楽でしたので、このEntity FrameworkはSQL Server 相手なら悪くないパフォーマンスだから世の中の多数の人達は何ら問題なく使っているのかも? マイグレーションとかも不要だったし...でも、サーバー立ち上げてとか避けたくSQLiteに落ち着いたので、ここは自分自身が選んだ道だからやるしかないのかな^^;
ほんの小さなテーブルの1レコード取得してくる位はEnity Frameworkでも行けるんじゃないかと手を抜くと、普通に遅かった。なので、今回全てのDBアクセスはEntity Framework抜きで行く。なら、Microsoft.EntityFrameworkCoreだったかな?これも本来不要だったかもですが、なんだったか必要な時があった気がする。ああ、AsNoTrackingか^^; これも使わないからマイグレーションのみの理由で使う事になるのか。
で、基本的なアクセスはSQL文用意してExecuteReader()使ってレコード取得して処理するんですが、以前データ登録ではExecuteNonQuery()で戻り無しだったけど、レコード受けるヴァリアント型を解放しないと
'DataReader already active on this command'
ってエラーが出る。なので、使い終わったらDisposeAsync()で空にしておけば問題ない感じです。
追記 2022/02/15 16:39
上記DisposeAsync()ですが、問題は解消されたので間違いではないと思われますが、本来普通にClose()すれば良い感じなのでこちらに変更。
ちょっと気になり、グーグル先生に確認するとまあね、普通に回答が得られました。自分の勉強不足とかではないと思われますw これってMSの体質? 部外者からは何とも言えないけど、世の中MS中心に回ってるので、これを避けて通る技量はユーザーに求められるのが現状かな? だだ、理想と現実はって話になるとね~^^; 便利機能なのは事実で、これによって簡素化され作業が捗るのは否めません。 しかし、このトレードオフで激遅なのはほぼ全てのユーザーが許容しないのは事実の様で、リリースされた新機能習得に時間を割いて得るものが無いのであれば、結果的に無駄な機能である事は否めなく、理想と現実的な話は一般ユーザーは避けたい所です。
マイクロソフトって現状ではPCのマストな存在なので、そんな企業が無駄をユーザーに強要するのは本当に辞めてとしか言いようがないですねorz
大昔、世の中にADO.NETがやっと現れた頃に早速飛びついて今回やってる事と同じ事を試してデータベース作成に挑み、1年分のデータ登録に1日とか余りの激遅に一旦投げた事があるんですが、月日が流れても便利な機能にはその代償があるんですかね? それとも単に自分自身が消化不良で機能を生かし切れていないのか^^;
今回のEntity Frameworkやコードファーストも凄く便利な機能で、随分と楽にデータベース開発が出来る様になったな~と必死に書いてるんですが、60ギガバイトのデータベースが悪いのかな~っとかDB分割によるダイエットも結局7分割まで行いました。でも、アクセスが非常に遅く、使い物にならないな~っと。データベース作成時はSQLiteの特性(?)でトランザクション明示的にするとかで、Entity Frameworkを避けて手動でパラメーター用意して登録するって変更とデバッグに相当な時間を費やしました。
出来上がったデータベース参照もまあ、もしかしたらDbContextのコンストラクタを上手く書き上げればクリア出来るものなのかもですが、デーベース作成時と同様に自力でオープンするスタイルに変更してみました。
using (var db = new KSD_DB())
{
var races = db.RACEINFO.Where(r => r.JOUCD.StartsWith("0") ||
r.JOUCD.StartsWith("1"))
.OrderByDescending(r => r.KAISAIBI)
.AsNoTracking()
.ToArray();
foreach (var race in races)
{
って感じで書いてたものを
SqliteConnectionStringBuilder sqlBuilder = new SQLiteConnectionStringBuilder()
{
DataSource = "KSD_DB.db",
ReadOnly = true
};
using (SQLiteConnection con = new SQLiteConnection(sqlBuilder.ToString())
{
con.Open();
using (SQLiteCommand cmd = new SQLiteCommand(con))
{
cmd.CommandText = "SELECT KAISAIBI FROM RACEINFO " +
"WHERE JOUCD LIKE '0%' OR JOUCD LIKE '1%' " +
"ORDER BY KAISAIBI DESC";
var races = cmd.ExecuteReader();
while (races.Read())
{
としてみると、数分掛かっていたツリービュー表示が数秒とやっと期待通りの反応になってくれました。もっと勉強してEntity Frameworkを使いこなせば、やりたい事が数秒で出来るのかは不明ですが、ここは作業進める事を優先します。ただ、Entity Frameworkってもうリリースから随分経つ訳で、あんな激遅では誰も使わない筈なので使い方把握出来てないだけと信じたいですね。そして、理解出来る日が近い将来来る事を願いグーグル先生に色々教えて貰えればと思います^^
昨日行ったフルセットアップは結局金曜日の夜は修正のみで一旦終了し、土曜日の朝から追加修正して開始。終わったのは日付回って今日午前0時過ぎでした。14時間43分とか掛かってまして、やはり62ギガバイトとかの巨大なDBファイルとなりました。追加のアップデートデータも入れ込んだ後に最適化すると、ギリ60ギガバイト切りました(笑) で、追加作業してたんですが、ある表示をするのに数分とか掛かる事が分かりました。最初は何かハングでもするミスコーディングでもしたのかと思い、一旦PCから離れて戻ると表示はされてたんですが、これでは使い物にならない様な^^; DB最適化もアプリ固まる状態で3時間強だったかな。
どう考えても、この巨大DBファイルは現実的ではないよな~っと。で、分割する事にします。4分割綺麗に15ギガバイトずつにはならないとは思うが、4分割してみようかと。エンティティ定義を大きなテーブルを別々のコンテキストにすれば良いだけだと信じて、作業してみます。分割後に再度フルセットアップして、その時間。最適化の時間。で、問題の表示時間等がどの程度短縮されるか楽しみに作業進めてみます^^
追記 2022/2/6 22:10
簡単には4分割出来ないと判断して、取敢えず3分割に。大きくなりそうなテーブル3つを別コンテキストにするんですが、2つは関連があるので、この2つを別コンテキスト、更に巨大になっていると思われる1つのテーブルを別コンテキストという感じにして、プロジェクト内に3つのコンテキストが存在する事になりました。
ここで、今まで同様にAdd-Migration xxxとUpdate-Databaseをしようとするが
More than one DbContext was found. Specify which one to use. Use the '-Context' parameter for PowerShell commands and the '--context' parameter for dotnet commands.
とか言われて処理されない^^; グーグル先生に確認すると
Add-Migration xxx -Context context1
Update-Database -Context context1
Add-Migration xxx -Context context2
Update-Database -Context context2
って感じでオプションパラメーターで指定する必要がある事が分かった。今回はもう1回の計3セットする必要があった訳だが、それを済ませてフルセットアップ開始してみた。フルセットアップは時短されないとすると明日の昼過ぎに終わるかな^^;
追記 2022/2/7 9:22
今もフルセットアップ中なんですが、エクスプローラでDBサイズ確認すると既にメインDBは45ギガバイトorz 余りダイエット出来てない様です。これでは期待薄なので、一応終了までは今回の結果確定用に続け、午後終了後に当初の計画通り4分割処理してみようかと。これすればメインDBのダイエットはもう少し効果あるんじゃないかと思うので、それから効果確認してみようかと思います。
追記 2022/2/7 12:37
やっとフルセットアップ完了。14時間19分で、24分程度短縮された^^; 最適化前にメインDBは58ギガバイトと少しスリムになりましたが、まあ、確かに分けたコンテキストは3ギガバイトと1ギガバイトで3ギガバイトの方が単一テーブルなので、確かに巨大テーブルで分離したのは良かったのかもですが、効果自体は期待出来ないかも。なので、分割作業進めてみる。
追記 2022/2/7 13:50
分割作業は結局6分割まで進めてみた。これで実用的じゃなかったらっとか考えたくもないが、分割後のフルセットアップ開始はしたので、明日の明け方に終わるのかな~^^; 分割ダイエットによるセットアップ時間の短縮はそれ程期待は出来ないとは思う。例の1テーブルで3ギガバイトなコンテキストは1年分のデータ登録に40分程度掛かる感じなのは把握した。これ、確か2004年頃から提供されているので、ここまで18年分とかある訳で、これだけでも12時間掛かる計算ですorz ってか、逆に言えば、これ見捨てれば2時間程度で終わるのか^^ 今回の作業終わったら、しばらくこのモンスター除外して諸々進めるのか吉かな。
追記 2022/2/8 14:30
今日早朝にセットアップが終わってたんですが、痛恨のポカミスorz コンテキスト移動してるのに古いままのアクセスしようとしてのエラーで終了とか。まあ、本当の終わりの部分だったので14時間24分とかだった模様で分割での時短はもう無い感じですかね。問題の修正も終えて朝再トライ掛けようとするがエラーが出るとか...データ提供元がメンテに入ってたので、強制的に休憩w その間にも出来る修正はしてみました。しかし、こんなメンテも本来なら一般ユーザーの影響が少ない夜中に行う感じなのに普通に昼間に行う辺りが、親方日の丸ってな感じなのがね~^^;
まあ、分割は大体成功してる感じで、予想通り巨大なテーブルは頻繁にアクセスするテーブルとは分離出来、まあ、その分離した側が50ギガバイト超えとか^^; 今回はフルセットアップ中にエラーが出での終了だったので、全DB削除してますので、サーバーメンテ終了したら、テスト的なセットアップして動作確認後に今晩再度フルセットアップして寝る感じになるのかなぁっと。