MySQLはconnect_by_isleaf MySQLメソッドまたはストアドプロシージャに似た機能を実装します

MySQLはconnect_by_isleaf MySQLメソッドまたはストアドプロシージャに似た機能を実装します

最近、特に異常なビジネス需要があり、テーブルがあります

テーブル「デモ」を作成します(
 `id` int(11) 符号なし NOT NULL AUTO_INCREMENT,
 `tid` int(11) デフォルト '0',
 `pid` int(11) デフォルト '1',
 主キー (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3000124 デフォルトCHARSET=utf8;

以上です。レコードの行数は 300 万行を超えます。各 pid はこの ID の最上位カテゴリを記録し、tid はその親カテゴリです。
ここでの要件は、ID を指定してそのサブセット メンバーをすべて見つけ、この pid の値を新しく指定した値に変更することです。 !
PHP で実行したところ、実行に約 50 秒以上かかり、非常に苦痛でした。 ! !
すべてのサブセットを再帰的に検索し、その PID を変更する必要があり、これは非常に手間のかかる作業です。

Oracle には connect_by_isleaf というメソッドがあり、すべてのサブセットを簡単に見つけることができますが、私は MySQL を使用しています...

そこで、ここではMySQLメソッドやストアドプロシージャを使用して実装した経験について簡単に書きます。

1つ目: MySQL方式

CREATE DEFINER=`root`@`localhost` FUNCTION `lvtao_demo_a`(rootId int) 戻り値 text CHARSET utf8
  SQLデータの読み取り
  コメント「デモ」
始める

sTemp テキストを宣言します。
sTempChd テキストを宣言します。

SET sTempChd =cast(rootId を CHAR として)。
sTemp を '' に設定します。

sTempChdがnullではない場合
  SET sTemp = concat(sTemp,',',sTempChd);
  SELECT group_concat(id) INTO sTempChd FROM demo where FIND_IN_SET(tid,sTempChd)>0;
終了しながら;

sTemp を返します。

終わり;

使用方法は

lvtao_demo_a(5)を選択します。

しかし、テストしていたところ、300 万個のデータがクラッシュしてしまいました。 ! !

行 1 の列 'sTemp' のデータが長すぎます

利点: シンプル、便利、再帰呼び出しレベルの深さに制限なし (max_sp_recursion_depth、最大 255)。
デメリット: 長さが限られている。

2番目のタイプ: ストアドプロシージャ + 中間テーブル

区切り文字 ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `sss`(IN pid int, IN rootid int)
始める
   
done INT DEFAULT FALSE を宣言します。
id TEXT を宣言します。
DECLARE cur1 CURSOR FOR SELECT id FROM demo WHERE tid=pid;
NOT FOUND SET done = TRUE の継続ハンドラーを宣言します。

max_sp_recursion_depth を 200 に設定します。
 
オープンcur1;
  read_loop: ループ
    cur1 を id にフェッチします。
    完了したら
      read_loop を終了します。
    終了の場合;
    INSERT INTO temp (rootid,zid) values ​​(rootid, id);
    sss(id,rootid) を呼び出します。
  ループを終了;
cur1 を閉じます。

終わり;;
区切り文字 ;

ハハハ、300万のデータもボールの中に詰まってるよ〜〜〜

別の方法を考えよう~~~~もうこれ以上は気にしない

以下もご興味があるかもしれません:
  • Linux 上の MySQL でストアド プロシージャを使用してレコードをバッチで生成する方法
  • Mybatis 呼び出し MySQL ストアド プロシージャのシンプルな実装
  • MySQL と Oracle の違いの比較: 5: ストアド プロシージャと関数
  • mysqlストアドプロシージャは重複データを判定し、挿入しません
  • Java で MySQL ストアド プロシージャを呼び出す方法の詳細な説明
  • MySQL データベースのストアド プロシージャによるツリー トラバーサルの実装
  • MySQL ストアド プロシージャの最適化の例
  • MySQL のストアド プロシージャの分析例とストアド プロシージャの呼び出し方法
  • MySQL ストアド プロシージャ、カーソル、トランザクションの例の詳細な説明

<<:  Vue の計算プロパティとリスナーの使用の概要

>>:  Docker で ElasticSearch をデプロイする方法

推薦する

Centos8 で yum を使用して mongodb 4.2 をインストールする方法

1. リポジトリファイルを作成するmongodb の公式インストール ドキュメントを参照し、次のスク...

JavaScript を使用して QR コードを解析する 3 つの方法

目次1. JavaScriptを使用してQRコードを解析する1. QR コードとは何ですか? 2.q...

MySQLのSeconds_Behind_Masterの詳細な説明

目次マスターの後ろの秒数オリジナルの実装最終マスタータイムスタンプマスターとのクロック差他の実行時間...

And キーワードを使用した MySQL の複数条件クエリ ステートメント

AND キーワードを使用した MySQL 複数条件クエリ。MySQL では、AND キーワードを使用...

SQLと各種NoSQLデータベースの使用シナリオの説明

SQL はメイントランクです。なぜ私はこのように理解するのでしょうか。技術的な観点からリレーショナル...

JavaScript タイピングゲーム

この記事では、タイピングゲームを実装するためのJavaScriptの具体的なコードを参考までに紹介し...

CentOS 7 でゲートウェイを変更して IP を設定する方法の例

Centos7 バージョンをインストールするときに、外部ネットワークへの接続を選択すると、外部ネット...

Vue の img の src 画像アドレスの動的スプライシングの問題について

Vue での img の動的スプライシングを見てみましょう。src 画像アドレス、具体的な内容は次の...

HTML 選択オプションの基本的な理解と使用

JavaScript での HTML (選択オプション) の詳細な説明1. 基本的な理解:コードをコ...

shtmlとhtmlの違い

Shtml と asp は似ています。shtml という名前のファイルでは、asp の命令と同様に、...

MySQLプロセス関数の一般的な使用例の分析

この記事では、例を使用して MySQL プロセス関数の一般的な使用方法を説明します。ご参考までに、詳...

Azure Container Registry を使用してイメージを保存する際の問題

Azure Container Registry は、Docker Registry 2.0 仕様に...

js配列のfind、some、filter、reduceの違いの詳細な説明

Array の filter、find、some、reduce メソッドの違いを区別し、使用シナリオ...

MySQL のロックに関する問題

ロックの分類:データ操作の粒度から:テーブルロック:操作時にテーブル全体がロックされます。行ロック:...

MySQL 5.7.33 インストール プロセスの詳細な図解

目次インストールパッケージのダウンロードインストール環境変数の設定インストールが成功したか確認する記...