一个 提高SQL 查询的讨论帖
idn(關鍵字),產品名稱,產品數量...
B表,有字段:idn,a_idn(記錄A表的關鍵字),工序,工時...
A表與B表是一對多的關系,
我想取到A表的明細及B表相關的總工時
sele?aa.*?from?a?aa?left?outer?join?
??(select?a_idn,sum(工時)?from?b?group?by?a_idn)?bb?on?aa.idn=bb.a_idn
這樣雖然取得到我要的結果,可是速度很慢,尤其是我還有其它的表需要這樣連接,一層套一層,導致速度奇慢無比,二千多條數據,要七八分鐘才得到結果.這樣肯定不行.
請問應該怎么寫才能提高查詢速度?急盼高手提點
不應該啊,我覺得1s內就應該搞定,就這么一個查詢,沒有別的么。
還有你說的兩千多條是之A表,還是B表?
語句并不復雜,不應該市語句的問題
A表加了條件才二千多條數據,今天客戶打電話來說,查詢時提示超時鏈接,我用SQL調試發現
就是這個問題,左鏈接套了六層,一層比一層慢,最后就超時了!
當然套一層左鏈接,慢是慢點,但還能出來,但是套多了就會鏈接超時!!!有沒有改善辦法?
實在沒法子只好用循環了,慘~~~~~~
你用視圖試試
你的業務邏輯很復雜么,應該不至于7,8分鐘的,不行的話,你就建臨時表吧,把中間結果放進去。
......如果只是單純的表與表鏈接速度很快,可是與GROUP?by的統計結果再左鏈接速度就明顯慢,我試試把統計做成用視圖后再鏈接會不會快
我的表不復雜,就是主表的[客戶,加工類型,項目名稱]都記的是代碼,要中文信息,得在另三個對照表里取,還有要兩個統計結果:到貨數和加工工時,分別匯算自另外兩個表.
所以左鏈接套了六層...
視圖是不會提高效率的,它只是為了控制權限,或是查詢格式。
不要使用LEFT?OUTER?JOIN
效率很低
你這樣寫吧
sele?aa.*?from?a?aa,??
??(select?a_idn,sum(工時)?from?b?group?by?a_idn)?bb?where?aa.idn=bb.a_idn
sele?aa.*?from?a?aa,??
??(select?a_idn,sum(工時)?from?b?group?by?a_idn)?bb?where?aa.idn=bb.a_idn
這樣寫有一個問題,不能把A表全部的數據顯示出來呀
能不能用存儲過程呢?
有這么夸張嗎?感覺SQL語句不復雜,我更復雜的都寫過,都用上游標了也沒有這么慢啊。要不LZ用臨時表試一下,臨時表記錄B表的總工時,這樣可能會好一點把
這種情況有一個通用的解決辦法:根據情況你建立一個或者多個臨時表,因為每個臨時表數據量都不多,所以不會出現數據庫鏈接超時的情況,萬一數據量比較大,執行時間比較久,你還可以用進度條標識進度.
可以這樣
select?a.產品名稱,a.產品數量?sum(b.工時)
from?A表?a,B表?b
where?a.idn?=?b.a_idn
group?by?a.產品名稱,a.產品數量
是不復雜,可能是左鏈接套得太多,尤其和GROUP?by的子查詢進行左鏈接,會影響查詢速度.
臨時表我一直沒敢用,
SELECT?*?INTO?#tmp?FROM?表,
如果網絡個多個用戶同時查詢,執得這條語句會不會沖突啊?臨時表會自動刪掉吧?
不會沖突的,會話結束就刪除了。
臨時表是微軟都建議盡量避免使用,用了肯定慢
優化一下索引試試
用查詢分析器的執行計劃看看慢在哪兒
我試過了,普通表左鏈速度很快,就是和GROUP?by的子查詢進行左鏈接,會影響查詢速度,
看來沒有什么好辦法了,我還是做循環得了~~~~~
sele?aa.*,b.a_idn,b.sum(工時)?from?a?aa?left?join?b?group?by?a_idn?on??aa.idn=bb.a_idn
循環會快?group?by?是會慢要按索引掃描表然后求和;b表的記錄數有多少
b表35824條數據,group?by?后35677條,.........
sele?aa.*,b.a_idn,b.sum(工時)?from?a?aa?left?join?b?group?by?a_idn?on??aa.idn=bb.a_idn
我試試,再問一下left?join?和left?outer?join是不是一樣的
sele?aa.*,b.a_idn,b.sum(工時)?from?a?aa?left?join?b?group?by?a_idn?on??aa.idn=bb.a_idn
按這個格式試過一次了,提示"在關鍵字?'group'?附近有語法錯誤。",不行啊
樓主是不是只有b表的數據3w條,那么你可以試試先讓a與b的關聯的結果插入到臨時表,再用臨時表進行下面的4個關聯,那樣應該可以快一些。
如果在select里用子查詢呢?比如:
sele?aa.*,(select?sum(工時)?from?b?where?aa.idn=b.a_idn)?as?工時
from?a?aa?
(可能更慢!)
凡是有子查詢的,一般都慢!
A表37316條記錄,取多少數據,視條件而定,或多或少不一定的.
與B表類同的還有C表,有近6萬條數據....
本來一個SQL語句就能搞定的,現在弄得煩死人了!
如果是sqlserver2000
那么可以用
declare?@temp?table(a?varchar(10),b?int)
insert?into?@temp?select?a,b?from?ab?where?a='a'
這樣的臨時表優化嵌套查詢
如果在select里用子查詢呢?比如:
sele?aa.*,(select?sum(工時)?from?b?where?aa.idn=b.a_idn)?as?工時
from?a?aa?
(可能更慢!)
凡是有子查詢的,一般都慢!
--------------------------
我試了一下,3萬條數據蠻快的,而且一條不少,真是非常感謝你!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
謝謝各位的幫忙!非常感謝!yeskert1的答案解決了我大問題,不然要重寫代碼了!
那樓主把你原來嵌套的group?by?都去掉呢,你那樣的寫法&子查詢應該沒有差別啊,無非是少了個group?by。
A表3萬條,B表3萬條,單純的left?outer?join速度很快,就是用group?by?速度明顯下降,
yeskert1的答案,我試的時候蠻快的,怎么結完貼回去再試,就慢下來了呢,不過比原來的超時,總算是快點了,至少不會超時了.
哈,我發現一個奇怪的現象,用yeskert1的辦法,加條件反而比不加條件時慢,
按理說加了條件,才二千條數據,應該更快才對,真是奇怪
用SQL查詢分析器,不加條件,14秒就涮出結果了,加了條件,1分半鐘已過,結果還沒出來.
淚奔~~~~~~~~~~~~~~~~~~~`
你把完整語句貼出來看看
>>加條件反而比不加條件時慢,
這是可能的,因為條件必然有比對的過程,字符串比較是耗時間的。group?by?a_idn導致慢也是這個原因。
一般,這時應該為表增加索引來改善速度。
能把完整語句貼出來嗎?
SELECT?*
FROM?(SELECT?c.*,?isnull(d?.wcsl,?0)?AS?wcsl
????????FROM?(SELECT?a.*,?isnull(a.sl?*?b.zgs,?0)?AS?zgs
????????????????FROM?(SELECT?a.*,?isnull(b.xzlx,?'?')?AS?xzlx_sm
????????????????????????FROM?(SELECT?c.*,?isnull(d?.qym,?'?')?AS?qym
????????????????????????????????FROM?(SELECT?a.*,?isnull(b.xmm,?'?')?AS?xmm
????????????????????????????????????????FROM?ww_wwjl?a?LEFT?OUTER?JOIN
??????????????????????????????????????????????xmk?b?ON?a.xm_dir?=?b.dir)?c?LEFT?OUTER?JOIN
??????????????????????????????????????ww_khdak?d?ON?c.khdm?=?d?.khdm)?a?LEFT?OUTER?JOIN
??????????????????????????????ww_xzlx?b?ON?a.xzlx?=?b.xzlx_path)?a?LEFT?OUTER?JOIN
??????????????????????????(SELECT?wwjl_idn,?SUM(gs)?AS?zgs
?????????????????????????FROM?ww_wwjl_gs
?????????????????????????WHERE?(sbname?<>?'@#$%')
?????????????????????????GROUP?BY?wwjl_idn)?b?ON?a.idn?=?b.wwjl_idn)?c?LEFT?OUTER?JOIN
??????????????????(SELECT?wwjl_idn,?SUM(dhsl)?AS?wcsl
?????????????????FROM?ww_wwdh
?????????????????WHERE?dhrq?>=?'2006-01-01'?AND?dhrq?<=?'2006-12-31'
?????????????????GROUP?BY?wwjl_idn)?d?ON?c.idn?=?d?.wwjl_idn)?DERIVEDTBL
WHERE?(cj?=?'機械四課')?AND?(wwrq?>=?'2006-01-01')?AND?(wwrq?<=?'2006-12-31')
ORDER?BY?xm_dir,?th
------------------
一共六個表:
ww_wwjl是主表,與以下五個表左連接
|---->xmk??(ww_wwjl.xm_dir=xmk.dir)
|---->ww_khdak?(ww_wwjl.khdm=xmk.khdm)
|---->ww_xzlx?(ww_wwjl.xzlx=xmk.xzlx_path)
|---->ww_wwjl_gs?(SUM(gs)?group?by?wwjl_idn?|?ww_wwjl.idn=ww_wwjl_gs.wwjl_idn?)
|---->ww_wwdh??(SUM(dhsl)?group?by?wwjl_idn?|?ww_wwjl.idn=ww_wwjl_gs.wwjl_idn?)
不知道有沒有講清楚~~~~
頭大了!太復雜了![:(]
-_-|||,不管了,循環循環
select?a.*,b....?
from?ww_wwjl?a?left?join?xmk?b?on?a.xm_dir?=?b.dir
???????????????left?join?ww_khdak?c?on?a.khdm?=?c.khdm
???????????????left?join?ww_xzlx?d?on?a.xzlx?=?d.xzlx_path
???????????????left?join?(SELECT?wwjl_idn,?SUM(gs)?AS?zgs?
??????????????????????????FROM?ww_wwjl_gs?WHERE?(sbname?<>?'@#$%')?
??????????????????????????GROUP?BY?wwjl_idn)?e?ON?a.idn?=?e.wwjl_idn
???????left?join?(SELECT?wwjl_idn,?SUM(dhsl)?AS?wcsl
??????????????????????????FROM?ww_wwdh
??????????????????????????WHERE?dhrq?>=?'2006-01-01'?AND?dhrq?<=?'2006-12-31'
??????????????????????????GROUP?BY?wwjl_idn)?f?ON?a.idn?=?f.wwjl_idn
WHERE?(cj?=?'機械四課')?AND?(wwrq?>=?'2006-01-01')?AND?(wwrq?<=?'2006-12-31')
ORDER?BY?xm_dir,?th
doud2006謝謝,不過如果符合條件的記錄數多的話,還是很慢很慢
你的關聯字段都是索引字段嗎,不用的字段盡量不寫,少出現*;結果對嗎,沒有重復關聯吧
不是啊,我沒有用索引,我沒有用過索引,只有ww_wwjl的idn是關鍵字
記錄數是對的,沒有重復的關聯
沒索引是全表掃描,當然慢,6個表關聯字段都加索引試試;如果這幾個表不是很頻繁更新不包括insert;?where?條件也盡可能用索引;
請問,加了索引,會不會影響我其它的查詢語句呀??????
呀,下班了,我明天來試.謝謝
索引會提高查詢效率,在數據發生變化時需要更新索引,會降低更新效率
我對索引不是很明白,在網上找了資料看看了,還有很多不懂的地方.
請問unique?values打上勾是不是就是群集索引了?
在非群集索引下,數據在物理上隨機存放在數據頁上,在范圍查找時,必須執行一次表掃描才能找到這一范圍內的全部行。
在群集索引下,數據在物理上按順序在數據頁上,重復值也排列在一起,因而在范圍查找時,可以先找到這個范圍的起末點,且只在這個范圍內掃描數據頁,避免了大范圍掃描,提高了查詢速度。
那么非群集索引與沒用索引不是沒區別了嗎?象我要匯算總工時,group?by,就需要用群集索引了是不是?
你可以查一下sqlserver2000的幫助CREATE?INDEX;解釋的很清楚了
我試過了,我對需要GROUP??by?的字段進行了聚集索引,速度快了好多哦!不知道會不會對其它操作有影響!我還要測試一下.不過,我先得向你道謝.可是我已經結貼了,不知道還有沒有其它辦法給你加分呀doud2006
不過我有一個問題,我現在只有一個字段group?by?,如果我還有別的字段也需要GROUP?by的話,但聚集索引只能做一次,那么是不是只能將建立索引放在程序里啊?這樣頻繁得刪除建立聚集索引可取嗎?
轉載于:https://www.cnblogs.com/cy163/archive/2008/10/16/1313079.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的一个 提高SQL 查询的讨论帖的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 也跟90后小朋友聊聊
- 下一篇: Internet Explorer 8