分頁的sql優化是平常開發中常常遇到的問題,筆者在此作一個經驗總結,並附上相應的實驗過程。html
若不想親自實驗的,能夠直接跳過這一節。但仍是建議你們作一下實驗,眼見爲實。mysql
本次實驗使用的數據是mysql官方提供的employee數據庫,mysql官方提供了一些測試數據庫,能夠在這裏找到https://dev.mysql.com/doc/ind...。sql
安裝好employee數據庫後,筆者出於測試修改了一下salaries表的結構,方便測試,修改操做以下:數據庫
//修改原表的主鍵爲id CREATE TABLE `test_salaries` ( `id` int(11) NOT NULL AUTO_INCREMENT, `emp_no` int(11) NOT NULL, `salary` int(11) NOT NULL, `from_date` date NOT NULL, `to_date` date NOT NULL, PRIMARY KEY (`id`), CONSTRAINT `test_salaries_ibfk_1` FOREIGN KEY (`emp_no`) REFERENCES `employees` (`emp_no`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=latin1; //導入原表數據 INSERT INTO test_salaries (id,emp_no,salary,from_date,to_date) SELECT NULL,emp_no,salary,from_date,to_date FROM salaries;
至此,實驗的準備工做完成。可先查看一下test_salaries表中有多少數據(如下測試基於該表)緩存
SELECT count(*)FROM test_salaries;
優化分頁SQL查詢的思路:測試
原始sql查詢語句:優化
SELECT * FROM test_salaries WHERE salary <= 94000 LIMIT 2677500,10;
原始sql查詢語句執行效果:spa
只查詢id的sql語句:設計
SELECT id FROM test_salaries WHERE salary <= 94000 LIMIT 2677500,10;
只查詢id的sql語句執行效果:code
優化後的sql語句:
SELECT * FROM test_salaries INNER JOIN (SELECT id FROM test_salaries WHERE salary <= 94000 LIMIT 2677500,10) AS lim USING(id);
優化後的sql語句執行效果:
而且咱們能夠注意到,這條語句的執行時間與上一條只查詢id的語句的執行時間很是接近。
原始sql查詢語句:
SELECT * FROM test_salaries limit 2844030,10;
原始sql查詢語句執行效果:
只查詢id的sql語句:
SELECT id FROM test_salaries ORDER BY id limit 2844030,1;
只查詢id的sql語句執行效果:
優化後的sql語句:
SELECT * FROM test_salaries WHERE id>=(SELECT id FROM test_salaries ORDER BY id limit 2844030,1) limit 0,10;
優化後的sql語句執行效果:
一樣的,咱們能夠發現後兩句sql的執行時間比較接近。
除了對sql語句進行優化,咱們還能夠在應用程序層面對分頁進行一些優化設計。