zenet_logo

-株式会社ゼネット技術ブログ-

【備忘録】orderを忘れるべからず(Postgresql)

お久しぶりです。

システム事業部の阿部です。

 

未来の自分が同じミスをしないように備忘録を書きます。

 【orderを忘れるべからず】

 

一覧画面を作っているときに、ページング機能がうまくいかないことがあったため記録に残します。

 

環境

Postgresql 9.2.24

 

起こったこと

 ページング処理の中で1ページ目に入りきらないデータが2ページ目以降で取得されるはずが、取得できない事象が起きた。

 

対象機能:書籍一覧

 テーブル構成

booksテーブル

ID uuid primary key
name varchar(255) 書籍名
author varchar(255) 著者
created_at timestamp  
updated_at timestamp  

 

20件の書籍を登録して一覧画面で表示したところ、どのページにも表示されないデータが存在することがわかりました。

 

【発行しているSQL】

(1ページ目)

SELECT id,name,author,created_at,updated_at FROM books LIMIT 10;

(2ページ目)

SELECT id,name,author,created_at,updated_at FROM books LIMIT 10 OFFSET 10;

 

原因

冒頭にもあることから容易に想像できると思いますが、orderをつけていないことが原因でした。

PostgreSQLでORDER BY区を指定しない場合の並び - komagataのブログ

にもありますが、orderを付けない場合ソート条件がPostgres側で設定されるため、1ページ目のデータ取得SQLと2ページ目のデータ取得SQLでソート順が異なるため、1ページ目に表示されたデータが2ページ目でも表示される/1,2ページのどちらでも表示されないデータが存在することになっていました。

  

対策

SELECT id,name,author,created_at,updated_at FROM books LIMIT 10 OFFSET 10 ORDER BY id ASC;

 

困った理由

 すべてのデータどのページでも出続ける ではなく、検索条件やページングによるSQL構成によって動きが変わってくるため、再現性がなく原因の特定に時間がかかってしまいました。

SQLを見ても全く正しいとしか思えず、かなり困惑しました。

今回は、本番リリースの前の検証でたまたま気が付いたので事なきを得ましたが、本番リリース後に初めて発覚すると考えるとゾっとします。