MySQLサブクエリでorder byが効かない問題の解決方法

MySQLサブクエリでorder byが効かない問題の解決方法

偶然にも、SQL ステートメントを異なる MySQL インスタンスで実行すると、異なる結果が生成されることがわかりました。

問題の説明

ビジネス シナリオをシミュレートするために、製品テーブル product_tbl と製品操作記録テーブル product_operation_tbl の 2 つのテーブルを作成します。構造とデータは次のとおりです。

次に、次のステートメントを使用して、すべての製品の最新の変更時刻を照会する必要があります。

product_tbl から t1.id、t1.name、t2.product_id、t2.created_at を選択し、t1 を左結合します (product_operation_log_tbl から * を選択し、created_at desc で順序付けします)。t2 を t1.id = t2.product_id でグループ化し、t1.id でグループ化します。

結果から、サブクエリは最初に product_operation_log_tbl 内のすべてのレコードを作成時刻 (created_at) の逆順に並べ替え、次にそれらを product_tbl と結合して製品の最新の変更時刻を調べていることがわかります。


リージョン A の MySQL インスタンスでは、製品の最新の変更時刻をクエリすると正しい結果が得られます。ただし、リージョン B の MySQL インスタンスでは、取得される変更時刻は最新ではなく、最も古いものになります。ステートメントを簡略化することで、サブクエリ内の order by created_at desc ステートメントがリージョン B のインスタンスでは効果がないことがわかりました。

トラブルシューティングのプロセス

リージョンが MySQL の動作に影響を与える可能性はありますか? DBA 調査の結果、エリア A の MySQL はバージョン 5.6、エリア B の MySQL はバージョン 5.7 であることが判明し、次の記事が見つかりました。

https://blog.csdn.net/weixin_42121058/article/details/113588551

記事の説明によると、MySQL バージョン 5.7 ではサブクエリ内の order by ステートメントが無視されるとのことです。しかし、不可解なのは、ビジネス シナリオをシミュレートするために使用した MySQL バージョンが 8.0 であり、この問題は発生しないことです。 Docker を使用して MySQL 5.6、5.7、8.0 インスタンスをそれぞれ起動し、上記の操作を繰り返します。結果は次のとおりです。


ご覧のとおり、サブクエリ内の order by を無視するのは MySQL バージョン 5.7 のみです。 5.7 でバグが発生し、それ以降のバージョンで修正された可能性はありますか?

問題の根本原因

ドキュメントと情報の検索を続けると、公式フォーラムで次の説明を見つけました。

「テーブル」(および FROM 句のサブクエリ) は、SQL 標準によれば、順序付けされていない行のセットです。テーブル内の行 (または FROM 句のサブクエリ) は、特定の順序で並んでいません。そのため、オプティマイザは、指定した ORDER BY 句を無視できます。実際、SQL 標準では、このサブクエリに ORDER BY 句を含めることさえ許可されていません (ORDER BY ... LIMIT ... は、順序だけでなく、結果、つまり行のセットも変更するため、許可されています)。FROM 句のサブクエリを、指定も定義もされていない順序の行のセットとして扱い、最上位レベルの SELECT に ORDER BY を配置する必要があります。

問題の原因は明らかです。SQL 標準では、テーブルの定義はソートされていないデータ セットであり、SQL サブクエリは一時テーブルであることが判明しました。この定義によると、サブクエリ内の order by は無視されます。同時に、公式の回答では、サブクエリの order by を最も外側の SELECT ステートメントに移動する、という解決策も示されました。

要約する

SQL 標準では、サブクエリ内の order by は無効です。

MySQL 5.7では現時点でSQL標準に準拠しているため問題が露呈しているが、この書き方はMySQL 5.6/8.0でも有効である。

MySQL サブクエリで order by が有効にならない問題についての記事はこれで終わりです。MySQL サブクエリの order by が有効にならないことに関する関連コンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

参照ドキュメント

https://stackoverflow.com/questions/26372511/mysql-mariadb-order-by-inside-subquery

https://mariadb.com/kb/en/why-is-order-by-in-a-from-subquery-ignored/

以下もご興味があるかもしれません:
  • MySql ページングで limit+order by を使用する場合のデータ重複の解決策
  • MySQLでorder byを使用せずにランキングを実装する3つの方法のまとめ
  • MySQLのorder byとlimitを混在させる際の落とし穴の詳細な説明
  • MySQL の group by と order by を一緒に使用する方法
  • インデックスを使用して MySQL ORDER BY ステートメントを最適化する方法
  • MySQL のソートとページング (order by と limit) と既存の落とし穴
  • MySQLにおける(JOIN/ORDER BY)文のクエリ処理と最適化方法
  • MySQLは「order by」がどのように機能するかを簡単に理解します
  • MySQL の order by ステートメントの最適化方法の詳細な説明
  • MySQL での order by の使用に関する詳細

<<:  IE6/7 で絶対配置された要素が不可解に消えたりブロックされたりする問題を解決する方法

>>:  Vueはローカルストレージの追加、削除、変更機能を実装します

推薦する

MySQL 挿入時間の 8 時間の違いの問題の解決方法

MySQL挿入時の8時間の時差の問題を解決する通常、jdbc の URL にはいくつかのパラメータを...

MySQL 8.0.23 メジャーアップデート (新機能)

著者: Guan Changlong は、Aikesheng の配送サービス部門の DBA です。主...

クロスオリジン画像リソース権限(CORS 対応画像)

HTML 仕様書では、画像の crossorigin 属性が導入されています。適切なヘッダー情報 ...

CSSはマウスが画像に移動したときにマスク効果を実現します

1.マスクレイヤーのHTMLコードと画像をdivに配置する.img_div に入れました。 <...

Dockerコンテナ間で通信する3つの方法

Docker コンテナは互いに分離されており、相互にアクセスできないことは誰もが知っていますが、依存...

Vue3.0のさまざまなリスニング方法の包括的な概要

目次リスナー1.ウォッチエフェクト2.見る1.1 聴くための最初の方法1.2 聞く2つ目の方法1.3...

JavaScript における clientWidth、offsetWidth、scrollWidth の違い

1. コンセプトこれらはすべて Element の属性であり、要素の幅を示します。 Element....

mysql は sql ファイルを実行し、エラーを報告します エラー: 不明なストレージ エンジン 'InnoDB' ソリューション

問題を見つける最近、仕事で問題が発生しました。InnoDB タイプの SQL ファイルを実行すると、...

JS ES の新機能、変数分離割り当て

目次1. 配列の分離割り当て1.1 配列分離割り当てとは何ですか? 1.2 配列分離割り当てに失敗し...

JSの基本概念の詳細な紹介

目次1. JSの特徴1.1 マルチパラダイム1.2 説明1.3 シングルスレッド1.4 ノンブロッキ...

MYSQL の解凍版における中国語の文字化け問題の解決方法

MYSQLの解凍バージョンがインストールされます1: 解凍後、my.ini ファイルをコピーし、バイ...

MySQL データベースのパフォーマンス最適化の概要

目次なぜ最適化するのですか? ?どこから始めますか? ?解決策は何ですか? ? ?どうやって選ぶ? ...

MySQL の 3 つの浮動小数点型 (float、double、decimal) の違いと概要について簡単に説明します。

各浮動小数点型のストレージ サイズと範囲は、次の表に示されています。タイプサイズ範囲(符号付き)範囲...

MySQL サービスに iptables ファイアウォール ポリシーを追加するためのソリューション

MySQL データベースが Centos7 システムにインストールされており、オペレーティング シス...

JavaScriptはフォームデータの非同期取得を実装します

この記事では、フォームデータの非同期取得を実現するためのJavaScriptの具体的なコードを例とし...