10年以上前に面倒見てたシステムの改善点を今頃思いついたので書く。

 10年以上前に面倒見てたシステムの改善点を今頃思いついたので書く。

受注を管理するテーブルが有ります。
受注の状態を示す列があります。
NULLが初期値で、0が発送準備中、1が発送済みたいな感じです。
受注から次の段階に処理を進めるときに、新しい受注を検索するのにIS NULLを使っていた。
NULLの検索だからテーブル全体をディスクから読み込むというコストの高い処理をしなければならない。
大半が発送済の1が立つのでBtree indexは効率的ではありません。
OLTP系(webからも基幹システムからも受注テーブルに書き込む)だったのでビットマップインデックスを使えません。

どう改善するか?

まず、NULLの検索をやめることだ。
初期値を2にして受注済の検索を2で検索する。
次に、受注日時を並べ替えて、古い順から1つづつ読み込み、一番最初に初期値の2(更新前でいうところのNULL)が出た一つ前のレコードの日付を記憶しておく(この処理は1日置きとかに処理する)
その日付以降の受注のみを検索するようにSQLのWHERE句に日付の検索条件を加える。
つまり、処理済の受注レコードを検索しないように処理済以前のレコードを除外する条件を日付でつける。
日時ならなBtree Indexが有効に働き、全文検索のコストの高い処理を避けられる。
もう、10年以上前のシステムだからテーブル構造とかも更新されているだろうな。
まあ、悪夢のようなシステムだったから、テーブル設計者の能力がなかったんだ。
ちなみに、毎日処理する最古の2を探す処理は、前日の日付以降を探すようにwhere句に条件をつけること。コストはなるべく低くすること
トランザクション的には日次処理中(最古の受注を探し中に)に新しい受注を受注テーブルにinsertされないために、日次処理で受注テーブルをロックする必要があるのか、
いや、必要ない。トランザクションが開始してselectした時のレコードしか選択されない。つまり処理中のinsertされたレコードは選択されない。そもそも、常に新しい受注日時でinsertされる。


2015年6月10日水曜日に作成した記事だ。
amazonや711でコンビニ払いに期限がついているのは、btreeインデックスを有効にするためだ。
Evernoteもsqlで言うところのbetween A and Bみたいに、ノートの作製日を範囲で指定できたらいいのにな。
範囲指定の機能を付けてもだれも使わないか?

コメント

このブログの人気の投稿

dlsiteでダウンロードしたzipファイルが解凍時に文字化けする件について

2024年12月29日、あすけんダイアリー、体重、食事、運動