簡聊 limit 0,100 和 limit 10000000,100一樣嗎
正如題目所問。
其實不一樣的。這是 MySQL 中典型的深度分頁問題。
MySQL 的LIMIT m n工作原理是先讀取前 m+n 條記錄,再拋棄前 m 條,然后返回后面的 n 條數(shù)據(jù)。因此,當 m 值增大時,偏移量也增大,性能表現(xiàn)就會變差。
因此,LIMIT 10000000,100要比LIMIT 0,100的性能差得多,因為它需要先讀取 10000100 條數(shù)據(jù),然后再拋棄前 10000000 條。
limit 優(yōu)化
通常,在查詢數(shù)據(jù)時,如果已經(jīng)明確知道所需行數(shù),建議在查詢語句中使用LIMIT,而不是先檢索整個結果集再丟棄不需要的數(shù)據(jù)。
盡管我們前面提到,在深度分頁時,MySQL 也會先檢索全部數(shù)據(jù)再丟棄,但 MySQL 對LIMIT也進行了一些優(yōu)化。然而,以下優(yōu)化前提假設在使用LIMIT時沒有使用HAVING語句。
- MySQL 通常更傾向于執(zhí)行全表掃描,但如果您使用LIMIT只查詢少量記錄,MySQL 在某些情況下可能會選擇使用索引。
- 如果將LIMIT子句與ORDER BY子句結合使用,MySQL 會在找到排序結果的前 row_count 行數(shù)據(jù)后立即停止排序,而不是對整個結果進行排序。如果使用索引完成排序,這將非??臁?/li>
當使用索引來執(zhí)行 ORDER BY 子句時,MySQL 能夠利用已經(jīng)排好序的索引樹,從而快速找到所需的前 N 行數(shù)據(jù),而無需對整個表進行全表掃描和排序。
- 當將LIMIT row_count與DISTINCT一起使用時,一旦找到 row_count 個唯一的行,MySQL 就會停止。
- 使用LIMIT 0可以快速返回一個空的結果集,這是一種很有用的方法,用于檢測查詢是否有效。
- 如果ORDER BY不適用索引,并且后面還有LIMIT子句,優(yōu)化器可能會避免使用合并文件,而是使用內(nèi)存中的filesort操作對內(nèi)存中的行進行排序。
limit 和 order by
我們都知道,在查詢過程中,如果對某個字段進行排序(ORDER BY),而該字段存在重復值,MySQL 可能以任意順序返回這些行記錄,并且根據(jù)執(zhí)行計劃的不同,排序結果可能會有所不同。換句話說,排序結果可能是不確定的。
因此,當ORDER BY語句中有LIMIT時,每次查詢結果都可能不同。例如,下面兩次查詢的結果可能會有所不同:
mysql> SELECT * FROM ratings ORDER BY category;
+----+----------+--------+
| id | category | rating |
+----+----------+--------+
| 1 | 1 | 4.5 |
| 5 | 1 | 3.2 |
| 3 | 2 | 3.7 |
| 4 | 2 | 3.5 |
| 6 | 2 | 3.5 |
| 2 | 3 | 5.0 |
| 7 | 3 | 2.7 |
+----+----------+--------+
那么,解決這個問題的一個好方法就是在排序時不僅使用一個字段,而是再加一個字段,比如像 id 這樣保證不會重復的字段。
mysql> SELECT * FROM ratings ORDER BY category,id LIMIT 5;