2011-11-23 00:38

[MySQL] EXPLAIN 分析報告的意義

轉載自:PHP + MySQL 程式設計研習

  • table
    表示所引用的表格名稱。
  • type
    表示查詢時的「聯結類型」(join type),以下依序是「最佳」至「最差」的各種類型:
    • system
      表格中僅有一列。這是 const 類型的一個特例。
    • const
      表格中符合條件的只有一列。因為僅有一列,其值在後續的查詢中可被視為常數。
    • eq_ref
      表示在與其它表格的資料列結合時,此表格只有一列會被讀取。當 join 使用到資料表中的所有索引,並索引是 UNIQUE 或 PRIMARY KEY 時才會被用到。
    • ref
      表示在與其它表格的資料列結合時,此表格中所有符合的資料列都會被讀出來。這是當 join 只使用到部份鍵值(註),或此鍵非 UNIQUE 或 PRIMARY KEY 時才會用到(依照 join 的條件仍然無法選定單一目標列)。若因此符合的資料列數不多的話,它也算是一種不錯的「聯結類型」。
      註:我們指定「A+B」欄位為 index key,但查詢時只用到「A」欄位。
    • range
      表示將在一定範圍內執行搜尋的動作。
    • index
      與 ALL 相同,但只有 index table 會被瀏覽。這通常比 ALL 快,因為 index table 通常比原始資料表來得小。
    • All
      表示這項查詢將對整個原始資料表瀏覽一遍,是最不好的類型。
  • possible_keys
    表示 MySQL 能夠藉由哪些 index 來搜尋目標。
  • key
    表示 MySQL 實際藉由哪個 index 來搜尋目標。
  • key_len
    表示 MySQL 實際使用的 key 長度。若 index key 是由兩個欄位以上複合而成的話,您可以在此看見 MySQL 使用了 index 的多少部份。
  • ref
    表示哪個欄位(或常數)將被用來與 key 一起比對。
  • rows
    表示 MySQL 粗略估計在查詢的過程中,必須瀏覽的資料列數。
  • Extra
    顯示 MySQL 在解決這項查詢工作時的一些附加訊息。例如:「where used」表示 where 子句將會限制某些資料列的輸出。
2011-11-23 00:14

[MySQL] TEMPORARY 臨時表

最近為了解決一個效率太差的問題而找上這個東西,由於有一個資料表的筆數實在太多了,再加上好幾百個 query 都同時在同一個區段做查詢,剛好可以使用臨時表來處理這個問題,原本查詢需要的時間大概超過一分鐘,現在最多只要 10 秒,刷新後約 2 秒。

MySQL 的臨時表只會存在在 Session 期間,當 Session 結束後就會自動刪除,不同的 Session 的表名稱並不會衝突,所以就算用一樣的名稱也不會出現錯誤,臨時表只能用在 MEMORY,MyISAM,MERGE,或者InnoDB 引擎上。

-- 透過 SELECT 建立臨時表
CREATE TEMPORARY TABLE my_temp_table ENGINE=MEMORY
SELECT * FROM my_table WHERE col_1 > 1000

-- 為臨時表建立索引
ALTER TABLE my_temp_table
    ADD INDEX (col_1),
    ADD INDEX (col_1,col_2)

參考資料:
MySQL CREATE TABLE Syntax
mysql temporary table簡介
避免 MySQL 使用 temporary table on disk
2011-11-22 23:29

[PHP] 把多個圖片壓縮封裝並下載

<?php
$fileList = array(
    '/var/www/pics/001.jpg',
    '/var/www/pics/002.jpg',
    '/var/www/pics/003.jpg',
    '/var/www/pics/004.jpg',
    '/var/www/pics/005.jpg',
    '/var/www/pics/006.jpg',
);


/*建立臨時壓縮檔*/
$file = tempnam("tmp", "zip");
$zip = new ZipArchive;
$res = $zip->open($file, ZipArchive::CREATE|ZipArchive::OVERWRITE);
if ($res!==true) { exit('壓縮錯誤');}

foreach ($filePathList as $filePath){
    $zip->addFile($filePath, $fileName);
}
$zip->close();

ob_end_clean();
header('Content-type: application/octet-stream');
header('Content-Transfer-Encoding: Binary');
header('Content-disposition: attachment; filename=pics_list.zip');

readfile($file);
unlink($file); 
exit;

參考連結:PHP: ZipArchive - Manual