有關於儲存過程的一個笑話
我真的是上來講一個笑話的,這是個傳統笑話,需要慢慢講。
我同事離職以後,統計平臺的所有程式碼就被我接過來了。這個統計平臺是用MySQL搭建的,5.1版本,伺服器是DELL的,有16個CPU和32G記憶體,700G的data空間,說真的這個配置對於我這種喜歡IOE的人來說實在是看不下去。
接過這個系統後我發現有一個過程需要跑三個小時,從前4點開始跑,到早上9點前也就出來了,於是也就沒有什麼。可是後來因為生產伺服器壓力很大,ETL的 時間被推後了很多,導致我的過程只能7點開始跑,這樣子,加上資料入庫,這個系統的日報往往要11點甚至12點才能跑出來,領導問我為什麼沒有資料的時候 我真的不知道該如何狡辯。於是我想到了把計算過程遷移到Oracle上。我也這麼做了,效果很好,這個三小時過程Oracle只需要不到1分鐘然後 spool出來load data都比原來的過程快很多倍。於是我就安心的用起了Oracle。
但是我今天工程師精神氾濫了,我想知道為什麼同樣是資料庫,人家阿里能把效能調校的那麼好,我們就要等那麼久?
我跟蹤了一下,最慢的是這樣的一個SQL:
select distinct b.name from table_a a inner join table_b b on a.id = b.id group by b.name
其中A表1億餘資料,B表2千萬左右,資料量可以說已經很大了。a的ID有一個索引,explain了以後這個SQL也走了索引,兩個表都走了。這就很奇
怪了,於是繼續看執行計劃,extra那裡有個temp
table還有一個filesort。於是我開始想笑,這是誰啊,distinct了還要group
by一下b.name?於是我檢視了一下b的表結構,這個表上的name是有一個索引的。我於是懂了從前的程式設計師為什麼要畫蛇添足的加一個group
by。這在Oracle程式設計師看來是愚蠢的行為裡,其實蘊含了一個MySQL的小技巧。我接觸MySQL不長時間,但是通過讀各種書籍發現MySQL的索
引很有趣,尤其是聚集索引,整個InnoDB表就是一個索引。
扯遠了,這個SQL裡,就是因為這個group by讓b表也走了索引,但是,當時的程式設計師應該是忘掉了去掉前面的distinct,於是導致了悲劇的發生。
這個SQL完整版是這樣子的:
insert into table_c(day_id, name, flag) select '20131128', distinct b.name, 1 from table_a a inner join table_b b on a.id = b.id group by '20131128', b.name;
去掉了distinct以後這個SQL還是很慢,半天插入不了。table_c有很多索引,這是個典型的DW表,很大。於是我建了一箇中間表,只有一個字 段name,可是我發現插入的速度還是很慢,非常慢,於是我想起了幾天前我看的《高效能MySQL》,裡面169頁還是179頁講過頁分裂的概念,提及了 一個小技巧,就是每個表都應該有一個自增的主鍵,這樣子插入速度會有一定的提升,於是我把mid表改了,有兩個欄位:id,name,其中id是自增的主 鍵。這樣一來,插入mid表只需要5min左右,而把mid表用簡單的select語句插入table_c只需要20s。是我想要的效率。
我學習MySQL只有短短的幾個月時間,而且沒有時間從最基礎的開始學,都是需要什麼知識就趕緊去看《高效能MySQL》,這本書真不錯,當做一本救急用 的字典確實可以滿足作為一個開發人員的需要。當然了,我的定位是開發型DBA,這本書裡講管理入門的還比較少,我還是要好好學習。歡迎大家指正。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28207565/viewspace-1061702/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SQL 儲存過程裡呼叫另一個儲存過程SQL儲存過程
- 關於Entity Freamwork 儲存過程操作儲存過程
- laravel建立一個儲存過程Laravel儲存過程
- mssql 儲存過程呼叫另一個儲存過程中的結果的方法分享SQL儲存過程
- Oracle儲存過程乾貨(一):儲存過程基礎Oracle儲存過程
- oracle的儲存過程Oracle儲存過程
- 關於SQL server2008除錯儲存過程的完整步驟SQLServer除錯儲存過程
- mysql返回一個結果集的儲存過程小例子MySql儲存過程
- 儲存過程與儲存函式儲存過程儲存函式
- SQLSERVER儲存過程SQLServer儲存過程
- 呼叫儲存過程儲存過程
- mysql 儲存過程MySql儲存過程
- unidac儲存過程儲存過程
- firedac儲存過程儲存過程
- Oracle儲存過程Oracle儲存過程
- MySQL全面瓦解16:儲存過程相關MySql儲存過程
- Sqlserver中的儲存過程SQLServer儲存過程
- Mysql 儲存過程的使用MySql儲存過程
- 如何查詢一個儲存過程是否在執行儲存過程
- 程式設計師的相關笑話(一)程式設計師
- 如何把SQL Server中一個表,一個儲存過程,一個檢視等改為系統表,系統儲存過程,系統檢視等...SQLServer儲存過程
- JdbcTemplate調儲存過程JDBC儲存過程
- 造數儲存過程儲存過程
- 儲存過程——遊標儲存過程
- 儲存過程 傳 datatable儲存過程
- JAVA儲存過程(轉)Java儲存過程
- MySQL之儲存過程MySql儲存過程
- MySQL---------儲存過程MySql儲存過程
- linux呼叫儲存過程Linux儲存過程
- Winform呼叫儲存過程ORM儲存過程
- mysql儲存過程整理MySql儲存過程
- Oracle儲存過程-1Oracle儲存過程
- 關於SQL Server中儲存過程在C#中呼叫的簡單示例SQLServer儲存過程C#
- mysql和orcale的儲存過程和儲存函式MySql儲存過程儲存函式
- Sqlsugar呼叫Oracle的儲存過程SqlSugarOracle儲存過程
- mysql儲存過程的引數MySql儲存過程
- plsqlDevloper 儲存過程的除錯SQLdev儲存過程除錯
- 怎樣評價一個幾千行的 SQL 儲存過程SQL儲存過程
- 儲存過程效能低的解決方法之一儲存過程