這段時間碰到乙個模組,sql查詢特別的慢,一直在努力想辦法優化它。
問題的**,這是乙個生產加工的模組存在的問題,
主從記錄。
主表主要字段:狀態(未複核=0,複核=1,生產完成=3),id,主表記錄生產時間,客戶名稱,要求交貨日,下單人,下單時間等等,
從表主要字段:貨品編號,貨品名稱,生產數量,領料數量,主記錄id等等。
客戶的需求: 客戶要求主記錄狀態,僅顯示(未複核=0,複核=1,生產完成=3)是不夠的要把,(全部領料,部分領料,未領料)這些狀態都新增進來,並且可以查詢,在主記錄的grid中顯示出來。
解決方案:
(一)修改程式設計滿足客戶要求
原先設計程式的時候沒有考慮要把(領料總數和貨品生產總數)在主表記錄中記錄進去,如果但是記錄進去的話,現在做上面那個狀態就比較容易啦。現在要改程式是比較麻煩的,而且還有老資料調整的問題,已及程式上,修改,刪除從表記錄同步主記錄領料總數,生產總數的問題,基於這個考慮修改程式設計暫不考慮。
(二)通過改變查詢sql來達到這個效果。
sql思路1: sql 這邊的話,剛開始採用的是比較正統的思路:
1.將從表領料數量,生產數量資料安mainid分組做sum統計 作為字表c;
2.主表記錄去left join 字表c。
具體sql如下:
select c.總領料數量,c.總生產數量,a.* from 主表名稱 a
left join (
select sum(nvl(領料數量,0)) as 總領料數量,sum(生產數量)as 總生產數量,
fywdh
from 從表名稱 group by 從表mainid
) c
on a.id=c.mainid
這樣的話有了c.sl,c.yrksl就可以實現剛才那個狀態啦,
做乙個calcstate
如果主表mainstate = 0 ;value='未複核';
如果主表mainstate = 1 ;value='複核';
如果主表 總領料數量 < 總生產數量 ;value='部分領料';
如果主表 總領料數量 = 總生產數量 ;value='全部領料領料';
如果主表mainstate = 3 ;value='生產完成';
查詢也是很好做的: 按照上面來就可以啦。
這樣子如果從完成任務的角度看是已經好,但是實際程式執行起來,效果卻是很不理想,
原因就是這個left join一做,以前查詢速度是1秒,現在變成30秒以上,那還是網速好的時候。
客戶這個時候又提要求啦,這個生產加工模組實在是太慢啦,(我自己都覺得慢,汗啊!)
基於這個原因,我翻看相關的sql書籍,通過很多嘗試,將這段sql優化了下,
成功的將查詢速度從30縮減到5秒一下。那到底是如何做的呢?
預知正解 ,請看sql思路2。
sql思路2:
仔細分析客戶的需求,客戶要的僅僅是乙個領料狀態的顯示,和查詢,那我們滿足這個就可以;
基於這個考慮,總領料數量,總生產數量是不是可以不用在主表記錄中顯示出來,
在主的記錄中直接顯示領料狀態就可以啦。
思路有啦
著手改sql
sql中有個exists可以過濾資料,以前都是用在where 後面用的,我想是不是可以放在
case when then else end
這個裡面的when後面呢,如果可以這樣的話,
我是不是就可以直接的 出它的狀態來。
經過一番努力結果是欣慰的:
sql如下:
select
case when not exists (
select c.id from tuser_hpcb c
where c.main = a.frwdh
and nvl(c.fsl, 0) > nvl(c.fyrksl, 0))
then ''全部領料'' '
when not exists (select c.id from 生產加工從表 c
where c.fywdh = a.frwdh '
and nvl(c.fflag, 0) <> 4
and nvl(c.fyrksl, 0)> 0)
then ''未領料'' '
else ''部分領料''
end as ''領料狀態'', a.* from 生產主表 a '
where 再加上查詢條件。
其中select c.id from 生產加工從表 c 這塊也是要注意的,千萬不要寫成
select c.* from 生產加工從表 c 這樣的話,速度上會變慢很多,sql執行後所要空間也會增加,
同時因為c.id是有做索引的,速度也會加快,關鍵是不需要顯示那麼些,
我們這裡僅僅是要有個字段而已。
上面那段這段做好後,calcstate
value=dataset['領料狀態']
如果主表mainstate = 0 ;value='未複核';
如果主表mainstate = 1 ;value='複核';
如果主表mainstate = 3 ;value='生產完成';
這樣就好了,當然狀態查詢的sql也是要改改的;不過我想這裡就不需要我再提啦
直接在where用上exists
,就可以悉數解決問題。
MySQL基礎 大幅度提高效能方案,分割槽表
下面就筆者工作中遇到的時間問題,模擬一下情況對大家進行介紹.工作中仍然是海量資料出現的情況.每年大概會有幾億條記錄.而且資料的時效性比較強.但歷史資料仍然要求保留.這個時候經過分析和研究,最終決定通過時間字段進行分割槽.下面是分割槽表的建立 讀者門在插入了不同年份時間段以後,可以時間欄位為條件進行查...
MySQL基礎 大幅度提高效能方案,分割槽表
下面就筆者工作中遇到的時間問題,模擬一下情況對大家進行介紹.工作中仍然是海量資料出現的情況.每年大概會有幾億條記錄.而且資料的時效性比較強.但歷史資料仍然要求保留.這個時候經過分析和研究,最終決定通過時間字段進行分割槽.下面是分割槽表的建立 讀者門在插入了不同年份時間段以後,可以時間欄位為條件進行查...
大幅度增加和改良了input元素的種類
對於不支援新增input元素的瀏覽器來說,統一將這些input元素視為text型別 是一種專門用來輸入url位址的文字框,提交的時候如果這個文字框的內容不是url地質格式的文字,則不允許提交 專門用來輸入email位址的文字框,提交的時候如果該文字框中的內容不是email位址格式的文字則不允許提交,...