MySQLクエリでorderbylimitを使用するための隠れたトラブルと解決策



Hidden Troubles Solutions



MySQLクエリでorderbylimitを使用するための隠れたトラブルと解決策

データクエリを実行するときに並べ替えにorderbyとlimitを使用することが多く、バーやページの並べ替えの数を制限し、通常の使用では例外を検出しません。ただし、最近のプロジェクトでは、この方法を使用して、クエリを実行するときに重大な問題を見つけました。 Jobでデータをインポートする場合、同時にインポートされるデータが大量にあるため、データ作成時間DataChange_CreateTimeは、時間、分、秒、および同じ時間に対してのみ正確です。データ。 Order by Limitを使用してページをクエリし、特定の回数フィルタリングすると、結果に一貫性がなくなります。クエリの数(つまり、制限データ)が10と1000の場合、2つの結果の最初の10個のデータに一貫性がありません。データを照会して問題を見つけてください。解決策は後で提供されます。それを記録し、同時に間違いをしないようにしてください。

同様の問題のシナリオ

次の構造のテーブルがあります。
5000、フラグ0、pay_time
約5000のデータ、ほとんどのレコードには0に等しいフラグがあり、pay_timeフィールドのタイムスタンプ形式は正しいです。



制限を使用して、データをバッチで読み取ります。

select id, pay_time from order_customer_new where flag=0 order by pay_time asc limit 250, 10

データの読み取りプロセス中に、タイムスタンプが等しいレコードが2回読み取られ、特定のレコードが失われる可能性があることがわかりました。次の図に示すように、id = 465のレコードは失われます。
画像
画像
状況はどうですか、id = 465のデータは失われますか?公式情報については、以下の説明があります。
画像
おそらく次のことを意味します。Limitrow_countとorderbyを混在させると、mysqlは、クエリ結果全体を並べ替えて返すのではなく、並べ替えられたrow_count行を見つけてすぐに返します。インデックスで並べ替える場合、ファイルの並べ替えの場合は非常に高速になり、クエリに一致するすべての行(制限なし)が選択され、limit_required row_countが見つかるまで、選択した行のほとんどまたはすべてが並べ替えられます。 limitに必要なrow_count行が見つかった場合、Mysqlは結果セットの残りの行をソートしません。
要するに、順序の値が等しく、順序の不確実性が生じる必要があります。



解決

上記の場合に並べ替え結果の一貫性と正確性を確保したい場合は、新しい並べ替え条件を追加できます。特に、並べ替え条件の1つに一意の主キーフィールドを追加して、並べ替え結果が一意に決定されるようにすることができます。 、多くの場合、問題を解決できます。 たとえば、上記のクエリの並べ替え条件の1つに主キーIDが追加された場合、クエリの結果は完全に正しいものになります。
画像

注:この記事の例は直接使用しています https://blog.csdn.net/tsxw24/article/details/44994835 このブログ投稿の例、実際のプロジェクトの例は、プライバシーを考慮して引用されていません。しかし、その結果、解決策は実現可能です。参考までに。