ふくふくHukuhuku Inc.
EP.33Data Fetch 10分公開: 2026-09-02

社内のデータベースから取る ── 本番を止めないための作法

自社のデータなので好きに取れる、とはいきません。分析のための重い問い合わせが、業務システムの応答を遅くします。同じ社内だからこそ配慮が要ります。

#SQL#データベース#運用
執筆 / 監修
松尾 亮合同会社ふくふく 代表社員

データ基盤・データパイプライン構築 / BI / 生成 AI 活用支援を専門とするエンジニア (28 年)。 本記事は AI 利用ポリシーに基づき、生成 AI の補助で執筆 → 人間が監修・編集して公開しています。

プロフィール詳細
シェア

外部のに対しては、EP.03 で扱ったように相手への配慮を考えます。ところが社内のデータベースが相手になると、途端に遠慮が消えます。自社のデータだから、という感覚があるからです。

しかし実態は逆で、社内のほうが影響が直接的です。外部のサービスなら遮断されて終わりですが、社内の本番データベースを重い問い合わせで詰まらせると、業務そのものが止まります。注文が通らない、画面が開かない、という形で表に出ます。

この回では、社内のデータを取るときに何に気をつけるかを扱います。技術というより、運用上の作法の話が中心になります。

本番に直接向けない

最初に検討すべきは、が用意されていないかです。読み取り専用の複製先があれば、そこへ向けるだけで本番への影響がなくなります。多くの環境では既に用意されているので、まず聞いてみる価値があります。

複製先には反映の遅れがあります。数秒から数分ほど古い状態を見ることになるので、最新の値が必須の用途には向きません。分析用途なら、この遅れが問題になることはまずありません。

接続先を間違えないための工夫

設定ファイルに本番と複製先の両方を書いておくと、うっかり本番を指したまま実行する事故が起きます。分析用の処理からは、そもそも本番の接続情報を読めないようにしておくのが確実です。

重い問い合わせを避ける

の書き方でも負荷は大きく変わります。とくに効くのが、取る範囲を絞ることと、必要な列だけを選ぶことの2つです。どちらも当たり前に聞こえますが、探索的に触っているとつい全件を取ってしまいます。

全期間を1回で取ろうとせず、期間で分けて何度かに分けるのも有効です。1回あたりの負荷が下がり、途中で失敗しても EP.07 の要領で続きから再開できます。

期間で区切って取る。1回の問い合わせを小さく保つ
Python
from datetime import date, timedelta

def month_ranges(start: date, end: date):    """月ごとの (開始, 終了) を返す。1 回の問い合わせを月単位に抑える。"""    cur = start.replace(day=1)    while cur <= end:        nxt = (cur + timedelta(days=32)).replace(day=1)        yield max(cur, start), min(nxt - timedelta(days=1), end)        cur = nxt

def fetch_by_month(conn, start: date, end: date):    sql = """        SELECT id, created_at, amount        FROM orders        WHERE created_at >= %(from)s AND created_at < %(to)s    """    for a, b in month_ranges(start, end):        # パラメータで渡す。文字列を組み立てて埋め込まない        yield a, conn.execute(sql, {"from": a, "to": b + timedelta(days=1)})

上のコードで値をパラメータとして渡しているのは、文字列を組み立てて埋め込むと注入の余地ができるからです。社内のデータで、入力も自分が書いた日付だとしても、この書き方を習慣にしておく価値があります。

接続先を間違えない仕掛け

「本番に向けない」と決めても、設定を間違えれば向いてしまいます。人の注意力に頼らず、間違った接続先では動かない仕掛けを入れておくのが確実です。接続した直後に、そこが読み取り専用かどうかを確かめます。

取得した結果はに置き、EP.12 の要領で日付ごとにしておくと、後から範囲を絞って読めます。社内データでも、取り直しに時間がかかる点は外部と変わりません。

接続した直後に、書き込めない接続かどうかを確かめる
Python
def assert_read_only(conn) -> None:    """書き込める接続なら、その場で止める。    設定ミスで本番へ向いていた場合、ここで気づける。"""    try:        conn.execute("CREATE TEMP TABLE _probe (x int)")    except Exception:        return                      # 書けない = 読み取り専用。想定どおり
    conn.execute("DROP TABLE IF EXISTS _probe")    raise RuntimeError(        "書き込み可能な接続になっている。分析用の接続先を確認すること"    )

いつ実行するかを決める

同じ問い合わせでも、実行する時間帯で影響が変わります。業務のピーク時間を避けるだけで、多くの問題は起きなくなります。夜間や早朝に回すのが基本です。

月末や期末のように、業務側が重くなる時期も避けてください。定期実行に載せる場合、その日だけ止める仕組みがあると安心です。止め方が無いと、忙しい時期に手で無効化することになります。

社内データベースから取るときの確認事項
確認なぜ
読み取り専用の複製先があるか本番への影響を消せる
接続に使う権限は読み取りだけか誤って書き換える余地を無くす
実行する時間帯業務のピークを避ける
1回あたりの所要時間長いほど詰まりやすい
止め方が用意されているか忙しい時期に手で止められる

権限は読み取りだけに絞ってください。分析のための取得に書き込みは要りません。権限があると、いつか事故が起きます。データ基盤側の権限設計については 壊れないデータ基盤の作り方 で扱っています。次回は、もっと素朴な経路を扱います。

社内のデータだからこそ、影響が出たときに困る人の顔が見えます。外部の相手より配慮すべき、と考えておくくらいでちょうどよいと思います。

シェア

この記事の感想を教えてください

あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。

シリーズの外も探す:

まずは、現状を聞かせてください。

要件が固まっていなくて大丈夫です。現状診断と方針提案までを無料でお手伝いします。

無料相談フォームへ hello [at] hukuhuku [dot] co [dot] jp