項目背景:
公司有一個項目用的是oracle數據庫,用戶數據量比較大。有1200w+(其實也不多)。然后在分頁查詢的時候到300w左右的時候就比較慢了,大概要3s+,到600w左右的時候要6s+。其實這個表的查詢並不復雜。就是一個單表的數據分頁查詢。
原來的分頁SQL-1:
通過使用邏輯分頁行編號值ROWNUM進行分頁
SELECT * FROM (SELECT T.*, ROWNUM AS ROWNO FROM (SELECT CUST_ID, CUST_NAME, CUST_NAT, CERT_NO, ORG_ID, TO_CHAR(CREATE_DT, 'YYYY-MM-DD') AS CREATE_DT, GENDER FROM xx_xx WHERE 1 = 1) T) R WHERE ROWNO >= 3000000 AND ROWNO <= 3000050;
修改過的分頁SQL-2:
也是通過邏輯分頁編號值ROWNUM進行分頁
SELECT * FROM (SELECT T.*, ROWNUM AS ROWNO FROM (SELECT CUST_ID, CUST_NAME, CUST_NAT, CERT_NO, ORG_ID, TO_CHAR(CREATE_DT, 'YYYY-MM-DD') AS CREATE_DT, GENDER FROM xx_xxWHERE 1 = 1 AND ROWNUM <= 3000050) T) R WHERE ROWNO>3000000;
修改過的分頁SQL-3:
使用物理分頁行編號值rowid
SELECT CUST_ID, CUST_NAME, CUST_NAT, CERT_NO, ORG_ID, TO_CHAR(CREATE_DT, 'YYYY-MM-DD') AS CREATE_DT, GENDER FROM T2A_CUST_I WHERE rowid IN ( SELECT t2.rid FROM (SELECT t1.*, ROWNUM rn FROM (SELECT CUST_ID, CUST_NAME, CUST_NAT, CERT_NO, ORG_ID, TO_CHAR(CREATE_DT, 'YYYY-MM-DD') AS CREATE_DT, GENDER, rowid AS rid FROM xx_xx WHERE 1 = 1) t1)t2 WHERE rn>3000000 AND rn < 3000050);
分析:
1、ROWNUM和rowid的區別? ROWNUM是邏輯地址,表示查詢耨條記錄在整個結果集中的位置,同一條記錄查詢條件不同對應的rownum是不同的二rowid是不會變的。rowid是物理地址,用於定位數據表中某條數據的位置,是唯一的、不會改變的,查詢快
2、SQL-1和SQL-2都是通過ROWNUM來分頁的,效果為什么會有很大差距?這個網上很多都是說CBO優化模式,Oracle可以講外層的查詢條件推到內層查詢中,以提高內層查詢的執行效率。很多帖子都在。大家自己可以了解一下。
| 3000000-3000050 | 6000000-6000050 | 9000000-9000050 | |
| SQL-1 | 7.8s | 8s | 8.2 |
| SQL-2 | 2.2s | 4.4s | 6.5s |
| SQL-3 | 2.9s | 2.8s | 2.7 |
參考:
https://blog.csdn.net/zp19860529/article/details/114308856
https://www.cnblogs.com/hqbhonker/p/4755694.html
