web-dev-qa-db-ja.com

同じレコードが順序付けられたページ付けされたクエリで複数回表示される

一部のレコードは、次のクエリで複数の結果「ページ」に表示されます。

_SELECT 
    `description`,
    `wallpaper`
FROM
    `bbr_bar`
WHERE
    `country_id` = '2510769'
ORDER BY
    `online` DESC
_

たとえば、ID 99のレコードは最初の「ページ」(_LIMIT 10 OFFSET 0_)に表示されますが、最後のページにも_LIMIT 10 OFFSET 50_が表示されます。明らかにこれは起こらないはずです。

この問題は、次の状況で解消されます。

  • クエリをフィルタリングしない、または順序付けしない場合(_country_id_とonlineint(11)であり、外部キーではありません)
  • SELECT句から2つのフィールドの1つを削除すると(外部キーではなくvarchar(255)の両方)
  • someスキーマ内のテーブルまたはフィールドを削除した場合しかし、何時間も努力しても、どのテーブル/フィールドに影響があり、どのテーブル/フィールドが影響していないのか、はっきりとは言えません。ランダムのように見えます(私がそうでないことがわかっていても)。したがって、_CREATE TABLE_またはINSERTステートメントは関連がないと思うので、ここには貼り付けません。

確かに言えることは、すべてのテーブルをmysqldumpして新しいスキーマに復元しても、問題はまだ残っているということです。

(テーブルには他のフィールドがありますが、それらを追加/削除しても結果には影響しません)。

質問:

  1. 自分のスキーマで何かが破損していると結論付けても正しいですか?
  2. どうすれば修正できますか?

(MySQLバージョン:5.6.24 Win32 x86)

3
marcv

MySQLによると、バグではありません!!!

この動作に関する2つのバグレポートがあり、重大ではないと見なされます

これが、バグ#69732で表現された 根拠です

明確なORDER BYがない場合、結果の順序は未定義です。限目。

同じクエリを2回実行しても、結果の順序が変わっても問題はありません。あなたは決定論的な結果のように見えることに慣れているかもしれませんが、それは実際には幻想です。それは通常の場合に表示されるものですが、これを保証する何もありません。結果の順序は、統計が更新されると、インデックスツリーが再シャッフルされ、データが異なる物理マシン間でパーティション分割されるため、結果の順序がネットワークのレイテンシに依存するため、変更される可能性があります...

したがって、ページ分割が必要な場合は、一意であることが保証されているものに対してORDER BYを実行するか、一意でないシーケンス内の同一の値の並べ替え順序が確定的ではなく、事前の通知なしにいつでも変更できるという事実を踏まえてください。

あなたの特定のケースでは、onlineフィールドはおそらく十分に区別されていません。 (bbr_baronline)によってcountry_idにインデックスを付けても、これはまだ十分に区別されない場合があります。並べ替え順序(おそらく自動インクリメントフィールドまたはタイムスタンプフィールド)を操作するには、別の列を含める必要がある場合があります。

試してみてください!!!!

4
RolandoMySQLDBA

完全に順序付けられた確定的なORDER BY online, idページネーションの際に、重複したエントリが表示されることがあります。

  1. 10アイテムの最初のページを表示します。
  2. あなたが考えている間に、誰かが最初の10に分類されるページを追加します。
  3. 次に、10項目の次のページを確認します。 #10がこのページに流出しました。

または... 2.考えている最中に、3番目のアイテムが削除されました。 3.次に、10項目の次のページを確認します。おっとっと!アイテム#11がありません。

より多くの議論は、主にOFFSETの非効率性を目的としていますが、上記の「バグ」も指摘しています: http://mysql.rjweb.org/doc.php/pagination 。 (これらのバグはOFFSETではなくではありませんですが、それを使用している場合)。

2
Rick James