LINQの遅延評価がマイナスに働くケース

LINQに限らず遅延評価はパフォーマンスに対してプラスに働く、という説明が多いように思うが、劇的にマイナスに働くケースがあった。 商品の名前の先頭に応じてグループ分けし、残ったデータに対して同様にグループ分けする以下のようなコード IEnumerable<T> left = .... var sub1 = left.Where(l => l.StartsWith("AB")) left = left.Where(l => sub1.All(s => s.ID != l.ID)) var sub2 = left.Where(l => l.StartsWith("A") left = left.Where(l => sub2.All(s => s.ID != l.ID)) var sub3 = left.Where(l => l.StartsWith("B") left = left.Where(l => sub3.All(s => s.ID != l.ID)) ... このような分類が20弱続くケースで、1分たっても応答が返ってこない。 leftの型をIListとし、left = left.Where(l => sub1.All(s => s.ID != l.ID)).ToList()のように即時評価に書き換えると1秒せずに返ってくる。 デバッグ実行すると、left = left.Where(l => sub1.All(s => s.ID != l....

<span title='2020-05-30 00:00:00 +0900 +0900'>May 30, 2020</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;tack41

GROUP BY省略時の弊害(MariaDB)

MariaDB 10.4 にて SQLでSELECT句に集計関数のみを指定する場合、GROUP BYは指定しなくても実行できる。 が、ヒットするレコードがない場合に全データnullのデータが1件返されてしまう。 GROUP BYに指定すれば0件が返されるので、明らかにヒットする場合を除いてGROUP BYは明示的に指定したほうがよさそう。

<span title='2020-05-25 00:00:00 +0900 +0900'>May 25, 2020</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;tack41

WindowsのMariaDBメジャーバージョンアップ後の運用の注意

WindowsのMariaDBを10.2 -> 10.4のようにメジャーバージョンアップする場合について。 バージョンアップ自体は公式サイトの手順に従って行えば良い。インストーラにより、上記の場合はバイナリはC:\Program Files\MariaDB 10.4、データはC:\Program Files\MariaDB 10.2を参照するようになる。MySQLサービスの実行パスは "c:\Program Files\MariaDB 10.4\bin\mysqld.exe" "--defaults-file=C:\Program Files\MariaDB 10.2\data\my.ini" "MySQL" のようになる。 で、時間があるのでデータもバイナリも10.4のフォルダにするためにバックアップを取得した上で10.4をアンインストール、再度10.4をインストールすると、サービスが起動しない。 原因は上記実行パスのサービスがアンインストール時も消されずに残ってしまうためのよう。 MariaDBをすべてアンインストールした状態でsc delete MySQLを実行して残ったサービスを削除し、再度インストールすると正しい実行パスのサービスのエントリが生成される。

<span title='2019-11-03 00:00:00 +0900 +0900'>November 3, 2019</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;tack41

MariaDBのON UPDATE CURRENT_TIMESTAMPに対するUPDATEの動作について

リンク先同様、しばらく悩んでしまったのでメモ。 MySQLでON UPDATE CURRENT_TIMESTAMP で更新時にタイムスタンプを自動更新するように設定している場合でも、UPDATE前後で値に変化がなければタイムスタンプは更新されない。 [https://qiita.com/nao_tuboyaki/items/bef44862f6ddffd4f0b5][https://qiita.com/nao_tuboyaki/items/bef44862f6ddffd4f0b5)

<span title='2018-11-13 00:00:00 +0900 +0900'>November 13, 2018</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;tack41

Access 2003からMariaDBに移行

内製のAccess 2003アプリを、DB部分はMariaDBに移行している。 フロントは.Net(C#) ツールを使って工数を削減できないかと模索したが、以下のような正攻法で攻めるしかないと言う結論に達した。 Access側のテーブルにて、極力Not Null制約を適用する… 後述のデータ移行クエリ実行の際、NullがあるとINSERT SELECT 文がこけるため、Nullの場合とそうで無い場合で別クエリを実行する必要が出てくるため。 文字列型は、NULL=空文字と考えて問題ない場合がほとんどと想定されるので、以下の手順を機械的に実行する。 文字列でない場合はNULLを置き換えるべき値が自明でない場合も多いので、一旦NULL値固定で移行し、列ごとに個別で移行(UPDATE DEST.COL=SRC.COL WHERE SRC.COL IS NOT NULL) 対象列の空文字を許可する。 該当列を更新する部分にてNULLの場合は空文字に置き換える処理を追加 画面のフォームがデータと連結していてSQLではなくDoCmdで処理している場合、後付でSQLを組み込むと競合エラーが面倒なので、単純にフォームの値をNz関数でNullを置換してやれば良い ウィザードに従って作成した画面などで、データ更新処理を明示的に記載されていない場合は、フォームの追加・更新前処理イベントにてNz関数を適用する UPDATE文で該当列のNULLを空文字に置換 該当列にNOT NULL制約を適用。 MariaDB側に、同一レイアウトのテーブルを新規作成。参照制約も実装。 MariaDBのODBCドライバをインストールし、対象のMariaDBをODBC登録。 AccessのリンクテーブルとしてMariaDBのテーブルを登録 AccessのテーブルからMariaDBのテーブルにデータを流し込む(INSERT SELECT)クエリを作成、初回の移行を行う。 参照整合性制約から、移行可能な順番がはっきりする。 MariaDBのデータに対してアクセスするフロントプログラムを作成する。 移行後のテーブルレイアウトそのものでプログラムの動作検証が可能。 フロントプログラムの作成が完了したら、MariaDBの全データをTruncateしてデータの本番移行を行う。 データ移行の逆順で実行しても参照整合性制約からデータを削除できない場合がある。素直に参照整合性制約を一時削除し、データの削除完了後に再度作成する。 テーブル名や列名にスペースやマルチバイト文字が入ってて命名規則を満たしていない、明らかに数量データなのに文字列型になっている…といった問題はこれ以降にじっくりリファクタリングしていく。上記の手順とリファクタリングを同時に行うのはリスクが大きい。

<span title='2018-08-19 00:00:00 +0900 +0900'>August 19, 2018</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;tack41