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

推薦する

HTMLページをクリックしてダウンロードファイルを実装する2つの方法

1. <a>タグを使用して完了します <a href="/user/te...

リバースプロキシ設定を実装するためのユニバーサルnginxインターフェース

1. プロキシサーバーとは何ですか?プロキシ サーバーは、クライアントが要求を送信すると、それを直接...

Node.js でのブレークポイント再開の実装

序文通常のビジネスニーズ: 写真、Excel などをアップロードします。結局のところ、数 MB のサ...

js は複数の画像を zip にパッケージ化します

目次1. ファイルをインポートする2. HTMLページ3. メインコード4. 画像をbase64に変...

アルバムと写真をアルバムに保存するためのWeChatアプレット

私は現在、Xiao Nian Gao に似たビデオおよびツール アプリを開発しています。ユーザーが作...

CSSページ下部固定を実現する8つの方法の詳細な説明

ページを書いているときに、ページの内容が小さくてフッターがページの真ん中に留まってしまうといった状況...

MYSQL8.0.13 無料インストール版 設定チュートリアル例 詳細説明

1. ダウンロード、例として8.0を取り上げますダウンロードアドレス: https://dev.my...

フロントエンド開発一般マニュアル(ツール、Webサイト、経験などを含む)

今日は何もすることがなかったので、いくつかのツール(オンラインとクライアント)、よく使用する URL...

MySQL 5.7.18 アーカイブ圧縮版のインストールチュートリアル

この記事では、MySQL 5.7.18アーカイブ圧縮版をインストールする具体的な方法を参考までに紹介...

mysql8.0.11 winx64 のインストールと設定方法のグラフィック チュートリアル (win10)

mysql 8.0.11 winx64のインストールチュートリアルは以下のように記録され、みんなと...

Vue+js はビデオのフェードインとフェードアウト効果を実現します

Vue+jsはビデオのフェードインとフェードアウトを実現します。参考までに、具体的な内容は次のとおり...

MySQLクエリ最適化分析チュートリアルをステップバイステップで教えます

序文MySQL は、強力なクエリ機能、高いデータ一貫性、高いデータ セキュリティ、およびセカンダリ ...

WeChat アプレットの日付と時刻のコンポーネント (年、月、日、時間、分)

この記事の例では、WeChatアプレットの日付と時刻コンポーネントの具体的なコードを参考までに共有し...

ウェブサイトがhttpsを有効にした後のSSLのセキュリティ構成と検出

最近のウェブサイトでは SSL を有効にするのが標準となっています。ただし、SSL を設定した後も、...

純粋な CSS カスタム複数行省略記号の問題 (原理から実装まで)

テキストオーバーフローを表示するにはどうすればいいですか? どのようなニーズがありますか?単一行です...