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 をデプロイする方法

推薦する

AWS無料サーバーアプリケーションとネットワークプロキシ設定チュートリアルの詳細な説明

目次予防必要条件AWSアカウントを申請する仮想マシンの申請と有効化仮想マシンを申請するセキュリティグ...

Mysql の主キー インデックスと非主キー インデックスの違いについて簡単に説明します。

目次インデックスとは何か主キーインデックスと通常のインデックスの違いインデックスにはどのデータ構造が...

MySQLは変数を使用してさまざまなソートを実装します

コアコード -- 以下では、MySQLでのソート列の実装を示します -- テストデータ CREATE...

Linux の高性能ネットワーク IO と Reactor モデルの分析

目次1. 基本概念の紹介2. ネットワークIOの読み取りと書き込みのプロセス3. 5つのLinuxネ...

Windows Server 2016 でサービスを展開する方法 (グラフィック チュートリアル)

導入インストールするシステムの数が多い場合、USB フラッシュ ドライブまたは CD を使用した手動...

JavaScript プロトタイプの詳細

目次1. 概要1.1 プロトタイプとは何ですか? 1.2 プロトタイプを入手する2. プロトタイプの...

VirtualBox での CentOS 8.1 仮想マシンのインストールを最小限に抑える詳細なチュートリアル

1. 関連ツールと画像をダウンロードするダウンロードリンクバーチャルボックス: https://do...

HTMLの表のtbodyは上下左右にスライドできます

テーブル ヘッダーが固定されている場合は、それを 2 つのテーブルに分割する必要があります。1 つの...

MySQLの挿入文字化け問題を解決する方法

問題の説明: MySQL に中国語の文字を挿入する場合、または MySQL では中国語の文字が正常に...

Nginxを使用してストリーミングメディアサーバーを構築し、ライブブロードキャスト機能を実現する

前面に書かれた近年、ライブストリーミング業界は非常に人気が高まっています。伝統的な業界でのライブスト...

CocosCreator 入門チュートリアル: ネットワーク通信

ネットワーク通信の概要オンライン ゲームを開発する場合、必然的にネットワーク通信に対処する必要があり...

MySQL 5.7.17 圧縮パッケージのインストールと設定方法のグラフィックチュートリアル

インターネット上にはMySQL 5.7.17のインストールチュートリアルがほとんどなく不十分なので、...

Tomcatディレクトリ構造の詳細な説明

目次ディレクトリ構造binディレクトリconfディレクトリlibディレクトリwebapps ディレク...

Linux カーネル デバイス ドライバー カーネル デバッグ テクニカル ノート集

/****************** * カーネルデバッグ技術 ****************...

Dockerコンテナ監視とログ管理の実装プロセス分析

Docker の導入規模が大きくなると、コンテナを監視する必要があります。一般的に、Docker に...