今天檢查滿查詢日誌發現有個儲存過程查詢可以達17s
而且是訂單列表查詢,這個當然不能忍了,必須優化,接下來就是查詢原因優化過程。過程使用動態語句,首先使用滿查詢的語句條件提取出來靜態語句單獨分析:
提取結果如下:
table1 表資料100w+ table3表資料200w+
selectb.*為什麼這個過程要10s+ 呢?, a.value1,
a.value2,
a.value3,
a.value4,
a.value5,
a.value6,
from
table1 b
left
join
table2a
on b.order_no = a.order_no and b.channel_no =
a.channel_no
where1=
1and
exists (select
1from
table3 t
where b.order_no = t.order_no and t.ticket_no like
'%1792903240%')
order
by create_time limit 0, 20
主要原因在於 exists這個部分,因為 table3有200w的資料,並且迴圈式和外表掃瞄查詢,並且這裡的like是不會走索引的,只能全掃瞄,所以慢就很明顯了,由於是動態語句,並在儲存過程中,所以優化就是拆解exists這部分
主要思路就是 先從200w+ 的table3中查出來order_no 然後把order_no插入臨時表,然後再使用in 臨時表查詢,減少關聯掃瞄次數就能極大的優化查詢時間
前提: table3中的ticket_no 重複率非常低,200w+的資料 有200w的非重複,為什麼強調這個,臨時表在處理少量資料時效能很優異,(一般只在確定不能用索引的時候才使用臨時表,或者在儲存過程中某些固定資料使用次數非常多的時候使用臨時表,其他時候我一般不建議使用)
優化結果:
create優化後查詢時間1.2s左右,速度提公升十幾倍,效能提公升明顯temporary
table tmp_order_no (ticket_order_no varchar(100
));insert
into tmp_order_no select tp.order_no from t_passenger tp where tp.ticket_no like concat('
%',2903240,'%'
);selectb.*
, a.value1,
a.value2,
a.value3,
a.value4,
a.value5,
a.value6,
from
table1 b
left
join
table2a
on b.order_no = a.order_no and b.channel_no =
a.channel_no
where1=
1and b.order_no in (select ticket_order_no from
tmp_order_no)
order
by create_time limit 0, 20
drop
temporary
table
ifexists tmp_order_no;
臨時表使用
臨時表語法 會話型的,會話結束資料清空 create global temporary table test tmp id number,name varchar2 10 on commit preserve rows 事務型的,事務結束資料清空 create global temporary ta...
使用臨時表進行效能優化
這兩個月都在搞一儲存過程,快要被它搞出精神病了。主要是它執行的時間比較長,每次執行幾十分鐘是常有的事,幾個小時也不少見。甚至乎這幾天,執行了兩天一夜都還不知道何時會圓滿結束。等待本來就是乙個痛苦的過程,而這個過程要幾天幾夜,那我不瘋誰人瘋。這肯定是有問題的。執行時間超過1小時的都應該有問題。後來,改...
MySQL臨時表的優化方案
mysql 是全球最受歡迎的開源資料庫,作為開源軟體組合 lamp linux apache mysql perl php python 中的重要一環,廣泛應用於各類應用。web2.0 時代,風靡全網的社群論壇軟體系統 discuz 和部落格平台 wordpress 均基於 mysql 實現底層架構...