sqltoy-orm第一講:什麼才是最NB的分頁!

很多人見到文章標題以為是標題黨,帶著半信半疑的心態進來看一下,有些高手想順便打擊一下!

我告訴你沒有機會的!因為sqltoy是中國人創建的目前最強的orm框架,為中國新基建加油!

sqltoy-orm的開源地址: https://github.com/chenrenfei/sagacity-sqltoy

我們舉一個簡單的例子:

  1. 查詢員工信息,
  2. 顯示其:工號、姓名、崗位、部門、入職日期、手機號碼、郵箱;
  3. 查詢條件是:入職日期在2019年1月到2019年12月,姓陳的員工。
  4. 按照入職日期逆序
<code>select t1.STAFF_ID,t1.STAFF_NAME,t1.ORGAN_ID,
			       -- 子查詢崗位名稱,應該還有性別等,這裡簡化一下
			       (select dict_name from sys_dict_detail 
              where dict_type='POST_TYPE' 
              and dict_key=t1.POST_CODE) postName,
			       t2.ORGAN_NAME,
			       t1.DUTY_DATE,
			       t1.EMAIL,
			       t1.MOBILE_NO
			from  sys_staff_info t1 
			            left join sys_organ_info t2 
			            on t1.ORGAN_ID=t2.ORGAN_ID
			where t1.name like '陳%'
			          and t1.DUTY_DATE>='2019-01-01' 
                and t1.DUTY_DATE<='2019-12-31'
      order by t1.DUTY_DATE desc/<code>
  • 傳統的分頁是怎麼弄?

很多人的分頁是不管三七二十一select count(1) from (上面這段sql)

  • 再深入一點的考慮到了count優化和order by的干擾,基本上就覺得很強了
<code>select count(1) 
from  sys_staff_info t1 
          left join sys_organ_info t2   
			    on t1.ORGAN_ID=t2.ORGAN_ID
where t1.name like '陳%'
			     and t1.DUTY_DATE>='2019-01-01' 
           and t1.DUTY_DATE 
<='2019-12-31'/<code>
  • 我們再來優化,我們發現查詢條件完全落在了員工信息表上:

通過 @fast() 實現內部先分頁,select * from (select xx from tablex limit ? offset ?) t1 left join tabley t2。

其結果就是:先取符合條件的數據10條再跟其他表進行關聯,減少關聯數據的規模從而提升效率。

<code>     select   t1.*,
			       (select dict_name from sys_dict_detail 
              where dict_type='POST_TYPE' 
              and dict_key=t1.POST_CODE) postName,
			       t2.ORGAN_NAME
			from  @fast(select STAFF_ID,
                                    STAFF_NAME,
                                    ORGAN_ID,
                                    POST_CODE,
                                    DUTY_DATE,
                                    EMAIL,
                                    MOBILE_NO
                            from   sys_staff_info 
                            where  name like '陳%'
                                        and  DUTY_DATE>='2019-01-01' 
                                        and  DUTY_DATE<='2019-12-31'
                            order by t1.DUTY_DATE desc
                 ) t1 left join sys_organ_info t2 
			            on t1.ORGAN_ID=t2.ORGAN_ID
     /<code>
  • 很多人覺得到這一步應該無法再優化了!我告訴你還有!

我們發現分頁查詢總是分成了2步:1)取count總記錄;2)再取一頁數據結果,總計有2次查詢。我們有沒有辦法讓2次查詢變少?

sqltoy則提供了分頁優化器:在一定時效內,查詢條件一樣利用緩存存放count數量,避免每次都2次查詢

<code>
		 
		 
		
		
			=:beginDate 
                                   and  DUTY_DATE<=:endDate
                       order by t1.DUTY_DATE desc
                 ) t1 left join sys_organ_info t2 
			          on t1.ORGAN_ID=t2.ORGAN_ID
				]]>
		
		 
		 
	/<code>
  • 到這一步的時候大家覺得肯定無法再優化了,這裡引申一下第二講最神奇的緩存翻譯,我們預覽一下最終效果:

看見沒有:關聯數據字典表、機構表都取消了,變成了單表查詢,查詢出結果後通過緩存將名字翻譯出來。

<code>
		 
		 
		
		
		
      
		
		
			=:beginDate]
                        #[and  DUTY_DATE<=:endDate]
            order by t1.DUTY_DATE desc
				]]>
		
	/<code>

怎麼樣?沒有水分吧!動態條件sql是不是也很直觀簡潔!


分享到:


相關文章: