數據庫環境:SQL SERVER 2005
今天在生產庫里抓到一條跑得慢的SQL,語句不是很復雜,返回的數據才有800多行,
卻執行了34分鍾,甚至更久。
先看一下執行結果
我貼一下SQL。
SELECT a.dec_yt1 , b.dec_yt1 , a.dec_yt2 , b.dec_yt2 , a.dec_yt3 , b.dec_yt3 FROM ctlm8288 a , ( SELECT t.corr_id , t.clerk_id , ROUND(SUM(ISNULL(t.dec_yt1, 0)), 2) AS dec_yt1 , ROUND(SUM(ISNULL(t.dec_yt2, 0)), 2) AS dec_yt2 , ROUND(SUM(ISNULL(t.dec_yt3, 0)), 2) AS dec_yt3 FROM ( SELECT b.corr_id , b.clerk_id , CASE WHEN d.feetype_flag = '1' THEN ROUND(SUM(a.dec_sqty * c.fee_price), 2) END AS dec_yt1 , CASE WHEN d.feetype_flag = '2' THEN ROUND(SUM(a.dec_sqty * c.fee_price), 2) END AS dec_yt2 , CASE WHEN d.feetype_flag = '3' THEN ROUND(SUM(a.dec_sqty * c.fee_price), 2) END AS dec_yt3 FROM ctlm8666 a , ctlm8001 b , v_saft04 c , ctlm8206 d WHERE a.terminal_id = b.terminal_id AND b.dept_id = c.dept_id AND a.item_id = c.vitem_id AND c.fee_id = d.fee_id AND d.flag_t = 'Y' AND a.fiscal_year = 2015 AND a.fiscal_period <= 6 AND c.cur_year = 2015 AND b.tertype_id LIKE '0102%' GROUP BY b.corr_id , b.clerk_id , c.fee_id , d.feetype_flag ) t GROUP BY t.corr_id , t.clerk_id ) b WHERE a.corr_id = b.corr_id AND a.clerk_id = b.clerk_id AND a.fiscal_year = 2015 AND a.fiscal_period = 6
SQL的寫法沒太大問題,我試着執行下,然后就是漫長的等待過程...
30分過去了,還沒出結果,我看了執行計划,就知道問題出在哪了。
看了執行計划圈紅的地方,優化器對ctlm8666和ctlm8001表預估只有一行,然后對這2張表做下統計,看是否真的只有1行。
SELECT COUNT(*) FROM ctlm8666 a WHERE a.fiscal_year = 2015 AND a.fiscal_period <= 6--1650439 SELECT COUNT(*) FROM ctlm8001 b WHERE b.tertype_id LIKE '0102%'--229823
預估數據和實際數據差別很大,出現這種情況,很可能的原因就是統計信息出問題了。
對ctlm8666表收集統計信息,在跑的SQL很快就有結果了。
我重新執行了下,看收集統計信息后,SQL執行要多久,下圖是結果。
(本文完)