這幾天都在看一個效能調優的預存程序,該程序在客戶生產環境(資料庫為mysql 5.1 )的運行時間為30到40多分鐘,客戶的要求是提高
此預存程序的實作:
1.兩個表的查詢(由於業務需要,也涉及該表的子查詢),分別插入臨時表;兩個表的資料分別為310W+, 120W
2. 中間還需要做一些處理,將臨時表的資料group by插入到另一個臨時表;
3.最後將臨時表的資料group by插入到一張正式表,插入的數據140W+
接著這幾天就在優化性能的路上越走越遠,嚐盡了各種方法,也嚐到了各種苦頭。
一、我感覺這實現的邏輯有點複雜,然後按照我的想法把實現簡化了。然而性能並沒有改善。因為我的實作是把大數據量提到了前面,而後面的操作還得爭對這部分大數據量進行操作,例如group by。所以雖然我的實作在邏輯上簡化了,但是效能並沒有提升。
二、根據不同的邏輯標識,創建了兩套臨時表,這樣一張表的資料量就不會那麼大,希望給後面的操作減少些壓力。還是以失敗告終。原因是因為邏輯識別的設置,所有都是走的一套邏輯,第二套邏輯根本就只是走過過場,不會真正去查那百萬數據的表,所以壓力還是在那300多萬的表。
三、使用預處理語句。其實對預處理語句的機制不是太明白,只是聽說預處理的效率更高。效能還是沒提升,大概是因為沒有太多相似的查詢或插入吧。嗯,不是太明白預處理機制。
四、將子查詢拿掉,先用臨時表儲存這部分資料。這樣那300多萬數據的表還是得查兩次,沒啥性能提升。
五、將臨時表的引擎由myisam改為memory,資料庫的全域變數max_heap_table_size,tmp_table_size也設定為了1000M,同生產環境。結果還是報
The table 'tmp_item_bu_parter_price' is full
,所以說資料量太大,導致記憶體撐爆?
六、也是在邏輯上走不同分支,結果發現走的都是同一個邏輯。這個有點虧,之前在這方面考慮的時間也挺長,沒有先去查明客戶的設定。
七、多執行緒。由於儲存過程中使用了insert into ...select...的句式,而且where條件未中索引,所以造成了全表鎖定。而多執行緒的測試結果無疑就是鎖表了,有些資料執行失敗。
八、在邏輯上不以全量的方式插入,而是增量,可是那些已存在的資料還是得更新啊。所以效能應該差不多。
【相關推薦】
2. MySQL最新手冊教學
#3. 資料庫設計那些事
以上是分享自己三天的效能調優遇到的一些問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!