主要原因是offset limit的分頁方式是從頭開始查詢,然後舍棄前offset個記錄,所以offset偏移量越大,查詢速度越慢。
比如: 讀第10000到10019行元素(pk是主鍵/唯壹鍵).
使用order by id可以在查詢時使用主鍵索引。
但是這種方式在id為uuid的時候就會出現問題。可以使用where in的方式解決:
帶條件的查詢:
如果在分頁查詢中添加了where條件例如 type = 'a’這樣的條件,sql變成 :
這種情況因為type沒有使用索引也會導致查詢速度變慢。但是只添加type為索引查詢速度還是很慢,是因為查詢的數據量太多了。這個時候考慮添加組合索引,組合索引的順序要where條件字段在前,id在後,如 (type,id),因為組合索引查詢時用到了type索引,而type跟id是組合索引的關系,如果只select id ,那麽直接就可以按組合索引返回id,而不需要再進行壹次查詢去返回id
使用uuid作為主鍵不僅會帶來性能上的問題,在查詢時也會遇到問題。
因為在使用select id from table limit 10000,10 查詢id數據時,默認是對id進行排序,返回的是排序後的id結果,如果我們想按插入順序查詢結果,這樣查詢出來的結果就與我們的需求不相符。
聚集索引跟非聚集索引:聚集索引類似與新華字典的拼音,根據拼音搜索到的信息都是連續的,可以很快獲取到它前後的信息。非聚集索引類似於部首查詢,信息存放的位置可能不在壹個區域。對經常使用範圍查詢的字段考慮使用聚集索引。
InnoDB中索引分為聚簇索引(主鍵索引)和非聚簇索引(非主鍵索引),聚簇索引的葉子節點中保存的是整行記錄,而非聚簇索引的葉子節點中保存的是該行記錄的主鍵的值。
如果您的表上定義有主鍵,該主鍵索引是聚集索引。
如果妳不定義為您的表的主鍵時,MySQL取第壹個唯壹索引(unique)而且只含非空列(NOT NULL)作為主鍵,InnoDB使用它作為聚集索引。
如果沒有這樣的列,InnoDB就自己產生壹個這樣的ID值,
優先選index key_len小的索引進行count(*),盡量不使用聚簇索引
在沒有where條件的情況下,count(*)和count(常量),如果有非聚簇索引,mysql會自動選擇非聚簇索引,因為非聚簇索引所占的空間小,如果沒有非聚簇索引會使用聚集索引。count(primary key)主鍵id為聚集索引,使用聚集索引。有where條件的情況下,是否使用索引會根據where條件判斷。