[CodeIgniter] 記憶體的隱形殺手:Log all queries
本文最後更新於:2024年5月30日 晚上
一、前言
在寫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>';
}
執行結果:
從執行結果可以清楚的了解每個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