プロジェクトの背景処理中、今朝はフィールド 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の他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
NATこのようにして、仮想マシンのネットワーク カードはホストの VMnet8 に接続されます。この...
隠れる前に:隠れた後: CS: ...コードをコピーコードは次のとおりです。オーバーフロー:非表示;...
目次1. 関数を宣言する2. 関数の呼び出し3. 関数パラメータ4. 関数の戻り値5. 議論の使用6...
Nginx は、多くの優れた機能を備えた強力で高性能な Web およびリバース プロキシ サーバーで...
1. 設置環境1. HUAWEI mate x CPU i5 82500u、8g メモリ、独立グラフ...
問題の背景:再生中のビデオのスクリーンショットを撮る必要があります。ビデオはビデオタグを使用して再生...
目次1. classList属性2. 実用化以前の JavaScript では、最初にクラス属性を取...
Centos6.5にmysql5.7.19をインストールするための詳細な手順は次のとおりです。 1....
目次Vuex は単一の状態ツリーを使用するため、すべてのアプリケーション状態が比較的大きなオブジェク...
vuexとはvuex: vue.js専用に開発された状態管理ツールで、すべてのコンポーネントの状態を...
LocalStorageはブール値を保存します今日、ブール値データを保存するために localsto...
この記事では、Docker で構築された Laravel および Vue プロジェクトの開発環境を紹...
1. 背景DockerでRabbitMQをデプロイする際に、次の2つの問題が発生します。問題1: ス...
数日前、図書館はサーバー(Ubuntu 14.04)にセキュリティ上の脆弱性があり、時間通りに修復さ...
この記事では、Vueカウンターの簡単な実装コードを例として紹介します。具体的な内容は以下のとおりです...