プロジェクトの背景処理中、今朝はフィールド A を更新する必要があります。午後には、クローラー チームが仕様または画像のクロールを完了し、画像と仕様フィールドを更新する必要があります。単一のテーブルで数千万ページのディープ ページ フリップが行われるため、処理速度はますます遅くなります。 db.tb から a、b、c を選択 制限 10000 オフセット 9000000 しかし、時間は限られています。この問題を解決するより良い方法はあるでしょうか? 改善案深くページをめくることなくデータを更新する方法はありますか? データ特性を観察するこの単一のテーブルには、自動増分 ID 列があり、主キーです。データのクエリと更新を行う理想的な方法は、インデックス列に基づいています。 id=9999999 の db.tb から a、b、c を選択します。 db.tb を更新し、a=x、id=9999999 に設定します。 マルチプロセス各プロセスは特定の ID 範囲内でデータを処理するため、深いページ フリップが回避され、複数のプロセスが同時にデータを処理できるようになります。 定義ミッションハンドラー(すべてのミッション、ワーカーミッションサイズ): 「」 タスク リストは、タスクの合計数と各ワーカーのタスク数に基づいて計算されます。タスク リストの要素は (タスク開始 ID、タスク終了 ID) です。 例: タスクの総数は 100 で、各ワーカーのタスク数は 40 です。この場合、タスク リストは次のようになります: [(1, 40), (41, 80), (81, 100)] :param all_missions: ミッションの総数 :param worker_mission_size: 各ワーカーの最大ミッション数 :return: [(start_id, end_id), (start_id, end_id), ...] 「」 ワーカーミッションID = [] 現在のID = 0 current_id <= all_missions の場合: start_id = all_missions if current_id + 1 >= all_missions それ以外の場合は current_id + 1 end_id = all_missions、if current_id + worker_mission_size >= all_missions、そうでない場合は current_id + worker_mission_size start_id == end_idの場合: ワーカーミッションID[-1][1] == 開始IDの場合: 壊す ワーカーミッションIDを追加します((開始ID、終了ID)) 現在のID += ワーカーミッションサイズ ワーカーミッションIDを返す 単一のテーブル ID の最大値が 100 で、各プロセスで 20 個の ID を処理すると仮定すると、タスク リストは次のようになります。 >>> ミッションハンドラ(100, 40) [(1, 40), (41, 80), (81, 100)] それで、 並行.futures から ProcessPoolExecutor をインポートします main() を定義します: # 自動増分 ID の最大値 max_id = 30000000 # 単一のワーカーによって処理されるデータ量 worker_mission_size = 1000000 # 複数のプロセスを使用してミッションを処理する = mission_handler(max_id, worker_mission_size) 労働者 = [] 実行者 = ProcessPoolExecutor() idxの場合、enumerate(missions)のミッション: start_id、end_id = ミッション ワーカー.append(executor.submit(データハンドラー、開始ID、終了ID、idx)) データハンドラを定義します(開始ID、終了ID、ワーカーID): 合格 アイデアの要約
データ処理スキル後続処理のために、成功した処理と失敗した処理のデータIDを記録する # 処理ステータスを記録するために別のテーブルを使用します insert into db.tb_handle_status(row_id, success) values (999, 0); プログラムが異常終了するのを防ぐために、ループ内で例外キャプチャが実行されます。 データハンドラを定義します(開始ID、終了ID、ワーカーID): #データ接続 conn、カーソル = mysql() 現在のID = 開始ID 試す: current_id <= end_id の場合: 試す: # TODO データ処理コードパス except 例外を e として: # TODOレコード処理結果# データは次のcurrent_id += 1に移動する 続く それ以外: # 例外なし、次のデータの処理を続行 current_id += 1 except 例外を e として: 'worker_id({}): result({})'.format(worker_id, False) を返します。 ついに: # データベースリソースの解放 cursor.close() 接続を閉じる() 'worker_id({}): result({})' を返します。format(worker_id, True) 可能な限りバッチ送信を使用してデータベースデータを更新する sql = """db.tb を更新し、a=%s、b=%s を設定します (ID=%s の場合)""" 値 = [ ('a_value', 'b_value', 9999)、 ('a_value'、'b_value'、9998)、 ... ] # ネットワーク IO とロック取得頻度を削減するためのバッチ送信 cursor.executemany(sql, values) 上記は、単一のMySQLテーブルで数千万のデータを処理するアイデアの詳細な内容です。単一のMySQLテーブルで数千万のデータを処理することの詳細については、123WORDPRESS.COMの他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
序文負荷分散には nginx を使用します。アーキテクチャのフロントエンドまたは中間層として、トラフ...
シェルスクリプトはアクセス制御を設定し、複数回のログイン失敗後にIPをブロックしてSSHのブルートフ...
この記事では、タブ切り替えの虫眼鏡効果を実現するためのVueの具体的なコードを例として紹介します。具...
最新のソリューション: -v /usr/share/zoneinfo/Asia/Shanghai:/...
MySQL インストール パッケージをダウンロードします。mysql-8.0.11-winx64 を...
1. Oracle は大規模データベースですが、MySQL は小規模から中規模のデータベースです。O...
filterは通常、特定の値をフィルターするために使用されます。たとえば、フィールドが空だが、フロン...
フロントエンドプロジェクトのパッケージ化.env.productionを見つけて、自分のIPまたはド...
1. コマンドの紹介ipcs コマンドは、Linux のプロセス間通信機能の状態を報告するために使用...
1. nginxソースディレクトリに新しいrtmpディレクトリを作成し、git clone http...
Windows 64 ビット版 MySQL 5.7 以降の解凍パッケージにデータディレクトリ、my-...
最近のプロジェクトでフォームを作成するときに、コメント ボックスまで自動的にスクロールし、コメント ...
JPQL は Java Persistence Query Language の略です。 Java ...
情報を探すインターネットで見つかったいくつかの方法: autocomplete="off&...
XML/HTML コードコンテンツをクリップボードにコピー< div style = &quo...