一、模擬百萬級數據量,采用爆炸式增長方式
insert into mmw_product( product_name, product_price,product_stock,prodct_barcode,product_img,class_id,status,create_time,update_time )
select product_name, product_price, product_stock, prodct_barcode,product_img,class_id,status,create_time,update_time from mmw_product
百萬數據
二、普通分頁
1.普通分頁查詢sql語句(配合mybatis)
<select id="listPage" parameterType="java.util.Map" resultMap="beanMap">
SELECT * from <include refid="table" /> limit 100000,20;
</select>
2.在dao(持久化層)計算查詢時間
System.out.println("--------begin---------");
long beginTime = System.currentTimeMillis(); //開始查詢—毫秒
List<Object> list = getSqlSession().selectList(getStatement(SQL_LIST_PAGE)); //操作數據庫
long endTime = System.currentTimeMillis(); //結束查詢—毫秒
System.out.println("-------end-----------");
long result=endTime-beginTime;
System.out.println("查詢耗時:"+result);
3.使用postman發起查詢:
接口分頁查詢方法
4.觀察控制臺輸出結果,耗時18毫秒
18毫秒
5.使用explain分析語句,MySQL這次掃描的行數是20w+。
explain SELECT * from mmw_product limit 100000,20;
explain語句分析結果圖
總結:一個非常常見又令人頭疼的問題就是,在偏移量非常大的時候,例如可能是LIMIT 100000,20這樣的查詢,這時MySQL需要查詢100020條記錄然后只返回最后20條,前面100000條記錄都被拋棄,這種分頁MySQL需要從頭開始一直往后計算,這樣大大影響效率,代價非常高;
三、優化分頁
1.使用主鍵索引來優化數據分頁(配合mybatis)
<select id="listPage" parameterType="java.util.Map" resultMap="beanMap">
select * from <include refid="table" /> where id>(select id from <include refid="table" /> where id>=100000 limit 1) limit 20
</select>
2.觀察控制臺輸出結果,耗時12毫秒
12毫秒
3.使用explain分析語句,MySQL這次掃描的行數是10w+.
explain select * from mmw_product where id>(select id from mmw_product where id>=100000 limit 1) limit 20;
Paste_Image.png
總結:在數據量比較大的時候,我們盡量使用索引來優化sql語句。該例子優化方法如果id不是主鍵索引,查詢效率比第一種還要低點。當然查詢效率不僅僅是跟我們的sql語句、java代碼有關,跟應用的架構以及硬件有關,所以說架構很重要。
四、SQL邏輯查詢語句執行順序
(7) SELECT
(8) DISTINCT <select_list>
(1) FROM <left_table>
(3) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) HAVING <having_condition>
(9) ORDER BY <order_by_condition>
(10) LIMIT <limit_number>