iT邦幫忙

1

[CodeIgniter 3] 記憶體的隱形殺手:Log all queries

  • 分享至 

  • xImage
  •  

本文另外刊登於我的部落格: Hankz Blog

一、前言

在寫CI的時候是否曾經遇過out of memory的錯誤呢
CodeIgniter作為輕量化的PHP框架
db物件一直是操作資料庫的好幫手
簡化了下達sql指令時的操作
加快了開發的速度
但其實看似好用的工具裡說不定有著隱藏的問題

二、正文

$this->db作為一個操作資料庫的物件
有兩個官方文檔中幾乎沒有提到的參數:
$this->db->queries$this->db->query_times

這個功能其實是CodeIgniter提供給開發者查詢sql指令紀錄與執行時間的功能
可以看到每個sql語法花費的實際時間
直接看Code:

$times = $this->db->query_times;
foreach ($this->db->queries as $key => $query)
{
    $microsec = round($times[$key] * 1000, 4);
    echo '[' . $microsec . ' microseconds] ' . $query . '<br>';
}

執行結果:
https://ithelp.ithome.com.tw/upload/images/20210917/20139878LzO8sMXawj.png

從執行結果可以清楚的了解每個sql語法花費了多久的時間進行查詢
幫助開發人員進行效能優化
執行的所有語法都存在這個變數裡面,真是太方便了對吧~

但是

這個功能在CodeIgniter裡是預設開啟的
所以當今天需要進行大量的sql查詢時
這個功能就會默默地吃掉記憶體
甚至導致out of memory錯誤

如果沒有特別需要的話
可以在資料庫設定加上 'save_queries' => FALSE
如下:

$db['default'] = array(
	'dsn'	=> '',
	'hostname' => '',
	'username' => '',
	'password' => '',
	'database' => '',
	'dbdriver' => 'mysqli',
	'dbprefix' => '',
	'pconnect' => FALSE,
	'db_debug' => (ENVIRONMENT !== 'production'),
	'cache_on' => FALSE,
	'cachedir' => '',
	'char_set' => 'utf8',
	'dbcollat' => 'utf8_general_ci',
	'swap_pre' => '',
	'encrypt' => FALSE,
	'compress' => FALSE,
	'stricton' => FALSE,
	'failover' => array(),
	'save_queries' => FALSE,
	'port' => 3306,
);

或是在執行大量查詢前
先使用:

$this->db->save_queries = FALSE;

來避免log紀錄吃掉大量記憶體的狀況

三、結語

我們都知道使用框架非常方便
可以省去很多重複的動作
以CodeIgniter中的db物件來說
最大的幫助就是減少了每次都要防範SQL injection功夫
還有串接SQL語法的麻煩
但是框架最大的隱患就是
使用它提供的「方便
但卻不知道框架到底在背後做了什麼事情

我們需要思考一個問題:
你在使用這些方便的工具生成SQL語法時
真的知道它實際上執行的SQL語句長甚麼樣子嗎?
會不會程式效率很差的原因就出在框架?

這篇並不是鼓勵不要使用框架
而是想分享一個觀念:不要過度依賴任何工具
真的清楚自己做了甚麼事情
才不會哪一天被自己給坑了

環境

CodeIgniter 3


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言