プロジェクトの背景処理中、今朝はフィールド 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の他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
<br />HTML 言語では、タグを使用してテーブルにタイトルを自動的に追加できます。...
目次並べ替えクエリの最適化変更されたばかりのデータ行を繰り返し取得しないようにする遅延ロードされた結...
カルーセルアニメーションは、ページの外観とインタラクティブなパフォーマンスを向上させることができます...
MySQL のフィルタリングのタイミングは、集計関数で使用される where 条件と having ...
この記事では、例を使用して、MySQL でストアド プロシージャを作成し、データ テーブルに新しいフ...
MySQL 5.7.19 winx64 解凍版のインストールチュートリアルを収録しています。具体的な...
HTML ボタン自体を中央に配置するにはどうすればよいでしょうか? このアイデアは簡単に見つかります...
目次背景解決策1アイデア:コード:解決策2アイデア:要約する参照する背景日付と時間をフォーマットする...
導入この章では、主に Linux で FTP サーバーを構築するプロセスを紹介します。習得すべき重要...
目次リアクティブ機能使用法: toRef 関数 (理解するだけ)使用法: ref関数レスポンシブデー...
序文この記事を書いた主な理由は、チームリーダーが、ブラウザを使用してコンピューターのカメラを呼び出し...
find コマンドは主にディレクトリやファイルを検索するために使用され、一致のために複数のパラメータ...
1. インデックスの原則インデックスは、列内の特定の値を持つ行をすばやく見つけるために使用されます。...
HTML のセマンティクスはありふれた問題のようです。Google で検索すると、セマンティクスに関...
画像リンク <img src="" /> jsを使用してURLが有効...