# 為什麼不該用 offset & limit 來做 pagination 常會用見到有人用這段 sql 來做 pagination: ```SQL SELECT * FROM table_name LIMIT 10 OFFSET 40 ``` 但這段 code 只應該出現在 MVP,或是 row 很少的 table 中。 主要問題是因為他會產生 Full Table Scan (aka Sequential Scan),which is slow(因為 I/O 很慢) 換句話說,本來想要讀 500001 ~ 500020 的這 20 筆資料,上面的語句卻要先掃過 500000 筆根本不是所求的資料,這十分沒效率。 > The higher your OFFSET, the longer the query will take. Instead, 應該要這樣做: ```SQL SELECT * FROM table_name where id > 10 limit 20 ``` 這個叫做 cursor based pagination。 local 不該保留 offset,取而代之的,應該要保留最後要求的 Primary Key(id 之類的) 不過若要能做到這招,就需要 unique, sequential 的欄位,像是 unique integer ID 或 timestamp,這在某些情況下可能不樂見,就需要權衡。 ## Ref - [[https://codecharms.me/posts/rails-%E7%B6%B2%E7%AB%99%E6%95%88%E8%83%BD%E5%84%AA%E5%8C%96%E4%BA%8C%E8%B3%87%E6%96%99%E5%BA%AB%E7%B4%A2%E5%BC%95-database-index|[Rails 效能優化] 資料庫索引 Database Indexing]]