1.背景
- 最近要分頁來防止大對象產生,在oracle中分頁,用的這個方式
SELECT * FROM (
SELECT A.*, ROWNUM RN FROM (
SELECT c1,c2,count(*) over () total -----依靠count(*) over ()查出 數量總和
FROM TABLE_NAME
) A WHERE ROWNUM <= 40
)WHERE RN >= 21
2.執行結果
原理分析
1.分頁
- 這個sql一共分爲三層,
-
- 第一層直接查詢出結果,
-
- 第二層增加<=40的查詢條件,
-
- 第三層增加了>=21的查詢條件。
- oracle優化會直接把第二層的 <= 40 條件推倒第一層,這樣往外傳的時候就只傳40條,而不是所有數據。這樣效率就高了;如果把 <= 40 放在第三層,oracle優化不能把 <= 40 的查詢條件傳遞到最內層,往外傳遞的是所有數據,效率低。
- 爲什麼不把 <= 40放在最內層?
放到最內層,那麼 count(*) over()代表的總條數就顯示40了,而我們分頁時候是要獲取總條數的。
2. count(*) over()函數介紹
-
over()函數寫法over(partition by expr2 order by expr3),根據expr2對結果進行分區,在各分區內按照expr3進行排序;
-
分區partiton by 與 group by的區別
group by會將結果集按照指定字段進行聚合,結果集會縮減(就是比select * 要顯示的數據少了)
partition by會對結果集按照指定字段分層排列,結果集不會縮減(跟select * 結果一樣,count(*) over 結果作爲一列顯示) -
不指定 expr2 默認結果集爲一整個分區,就是查詢的所有結果了
-
over函數不能單獨使用,需要與row_number(),rank()和dense_rank,lag()和lead(),sum(),count()等配合使用。