我們做的后端項目一般都會有admin管理端,當管理端將要展示數據的時候,就需要用到分頁。所以分頁的考查在面試中也相當多。在mysql中進行分頁查詢時,一般會使用limit查詢,而且通常查詢中都會使用order by來排序。但是在表數據量比較大的時候,例如查詢語句片段limit 10000,20,數據庫會讀取10020條數據,然后把前10000條丟棄,把最后的20條返回給你,這種消耗是可以避免的,也是沒必要的。下邊介紹幾種優化方法:
1. 讓分頁操作在索引中進行
一般表中經常作為條件查詢的列都會建立索引,例如如下查詢
SELECT
msg_id,
msg_content
FROM message
ORDER BY
gmt_create desc
LIMIT 100, 20;
可以寫成如下方式
SELECT msg_id, msg_content FROM message INNER JOIN ( SELECT msg_id FROM message ORDER BY gmt_create LIMIT 100, 20 ) AS page USING(msg_id);
這樣當前查詢頁的內容就只會在索引中進行,當得到當前頁的msg_id再統一通過一個INNER JOIN得到最終要得到的數據詳情,避免了對大量數據詳情進行操作的消耗。當然JOIN操作也可以通過子查詢實現,不過書中介紹5.6之前版本的mysql相比子查詢還是優先使用JOIN。
2. 顯式指定要查詢的索引列范圍
如方法一中的gmt_create是建立索引的列,而且你也知道要查詢的時間范圍,這樣你就可以通過如下查詢語句:這樣數據庫通過一個范圍查詢就可以得到想要的數據。
SELECT
msg_id,
msg_content
FROM message
WHERE gmt_create BETWEEN #startTime# AND #endTime#
ORDER BY gmt_create desc
3. OFFSET作為查詢條件顯式指定
我們可以在查詢參數中顯式指定一個查詢時間,叫做lastVisitTime吧。我們查詢第一頁可以用如下語句:
SELECT
msg_id,
msg_content
FROM message
ORDER BY gmt_create desc
LIMIT 20
我們把讀出來的數據的最后一條數據的gmt_create字段記錄在lastVisitTime字段中,那么后邊頁的查詢就可以用如下語句實現:這種查詢方式,無論你查詢多少頁,分頁都不會是影響效率的因素。
SELECT msg_id, msg_content FROM message WHERE gmt_create < #lastVisitTime# ORDER BY gmt_create desc LIMIT 20;
4. limit在MySQL中的用法
limit是mysql的語法,select * from table limit m,n。其中m是指記錄開始的index,從0開始,表示第一條記錄,n是指從第m+1條開始,取n條。select * from tablename limit 2,4。即取出第3條至第6條,4條記錄。
注意m表示的是從第幾條數據開始讀取,並不是記錄的主鍵id號。(you know it)
5. limit與offset用法比較
SELECT keyword FROM keyword_rank WHERE advertiserid='59' order by keyword LIMIT 2 OFFSET 1; 該用法,limit后面跟的是2條數據,offset后面是從第1條開始讀取 **************************************************************************************************** SELECT keyword FROM keyword_rank WHERE advertiserid='59' ORDER BY keyword LIMIT 2 ,1; 該用法,limit后面是從第2條開始讀,讀取1條信息。 注意:Mysql中計數也是從0開始讀數的。
6. 優化Limit的用法
當一個查詢語句偏移量offset很大的時候,如select * from table limit 10000,10 , 最好不要直接使用limit,而是先獲取到offset的id后,再直接使用limit size來獲取數據。效果會好很多。
SELECT * FROM customers WHERE customer_id >= ( SELECT customer_id FROM customers ORDER BY customer_id LIMIT 10000, 1 ) LIMIT 10;
相關聯的一些查詢用法實例總結如下:
select * from table limit 5; --返回前5行 select * from table limit 0,5; --同上,返回前5行 select * from table limit 5,10; --返回6-15行 附:(sql server支持,而mysql不支持的一些用法) 1. select top 2 * from table; 選取表中前2條記錄 2. select top 50 persent from table; 選取表中50%的記錄
7. oracle是如何分頁的?
在oracle中采用ROWNUM實現分頁查詢: 1. 選取前5條記錄 SELECT * FROM Persons WHERE ROWNUM <= 5; 2. 從表Sys_option(主鍵為sys_id)中從第10條記錄開始檢索20條記錄,語句如下 SELECT * FROM ( SELECT ROWNUM R, t1.* FROM Sys_option WHERE rownum < 30 ) t2 WHERE t2.R >= 10