假設有一個千萬量級的表,取1到10條數據;
select * from table limit 0,10; select * from table limit 1000,10;
這兩條語句查詢時間應該在毫秒級完成;
select * from table limit 3000000,10;
你可能沒想到,這條語句執行之間在5s左右;
為什么相差這么大?
可能mysql並沒有你想的那么智能,比如你要查詢 300w開始后面10條數據;mysql會讀取300w加10條這么多的數據,只不過 過濾后返回最后10條而已!!!
那么如果解決這個問題呢;這里總結三種常用方法;
第一種簡單粗暴,就是不允許查看這么靠后的數據,比如百度就是這樣的
最多翻到76頁就不讓你翻了,這種方式就是從業務上解決;
第二種方法,在查詢下一頁時把上一頁的行id作為參數傳遞給客戶端程序,然后sql就改成了
select * from table where id>3000000 limit 10;
這條語句執行也是在毫秒級完成的,id>300w其實就是讓mysql直接跳到這里了,不用依次在掃描全面所有的行
如果你的table的主鍵id是自增的,並且中間沒有刪除和斷點,那么還有一種方式,比如100頁的10條數據
select * from table where id>100*10 limit 10;
最后第三種方法:延遲關聯
我們在來分析一下這條語句為什么慢,慢在哪里。
select * from table limit 3000000,10;
玄機就處在這個 * 里面,這個表除了id主鍵肯定還有其他字段 比如 name age 之類的,因為select * 所以mysql在沿着id主鍵走的時候要回行拿數據,走一下拿一下數據;
如果把語句改成
select id from table limit 3000000,10;
你會發現時間縮短了一半;然后我們在拿id分別去取10條數據就行了;
語句就改成這樣了:
select table.* from table inner join ( select id from table limit 3000000,10 ) as tmp on tmp.id=table.id;
這三種方法最先考慮第一種 其次第二種,第三種是別無選擇