2013-05-01 21:59

[C#] 利用 LINQ 解析 XML 至 POCO

menu_config.xml
<?xml version="1.0" encoding="utf-8"?>
  <menu_config>
    <menu title="文章管理" url="~/Article" target="" allow="">
        <submenu title="列表" url="~/Article/list" allow="" />
        <submenu />
        <submenu title="新增" url="~/Article/add" allow="" />
    </menu>
    <menu />
    <menu title="帳號管理" url="~/Admin" />
  </menu_config>


//using System.Collections.Generic;
//using System.IO;
//using System.Linq;
//using System.Xml.Linq;
//using System.Text;

public class MenuDataModel
{
    /*POCO 資料欄位*/
    public string Title { get; set; }
    public string Url { get; set; }
    public string Target { get; set; }
    public string Allow { get; set; }
    public string Icon { get; set; }
    public List<MenuDataModel> Submenu { get; set; }

    /*取得資料清單*/
    public static List<MenuDataModel> GetList(string menuConfigPath)
    {
        /*讀取 XML 檔案*/
        var xmlContent = File.ReadAllText(menuConfigPath, Encoding.UTF8);
        var menuDocument = XDocument.Parse(xmlContent);

        /*利用 LINQ 轉成 POCO*/
        return menuDocument.Root.Elements("menu")
        .Select(menu => new MenuDataModel
        {
            /*取得 Element 上的 Attribute*/
            Title   = (string) menu.Attribute("title"),
            Url     = (string) menu.Attribute("url"),
            Target  = (string) menu.Attribute("target"),
            Icon    = (string) menu.Attribute("icon") ?? "Item",
            Allow   = (string) menu.Attribute("allow"),

            /*取得子層級 Element 上的 Attribute*/
            Submenu = menu.Elements("submenu")
            .Select(sub => new MenuDataModel
            {
                Title   = (string) sub.Attribute("title"),
                Url     = (string) sub.Attribute("url"),
                Target  = (string) sub.Attribute("target"),
                Icon    = (string) sub.Attribute("icon") ?? "Item",
                Allow   = (string) sub.Attribute("allow"),
            }).ToList(),
        }).ToList();
    }
}


void Main()
{
    var path = @"D:\menu_config.xml";

    List<MenuDataModel> list =  MenuDataModel.GetList(path);

    list.Dump();
}
2013-05-01 21:42

[C#] 取得 URL 頁面上的 title 內容

//using System.Net;
//using System.IO;
//using System.Text;

string url = @"http://msdn.microsoft.com/en-us/library/az24scfc.aspx";
string title = String.Empty;

WebResponse response = null;
WebRequest request = WebRequest.Create(url);

/*設定最長執行的毫秒數*/
request.Timeout = 10000; 

try{
    /*取得 URL 頁面資料*/
    response = request.GetResponse();
    StreamReader stream = new StreamReader(
        response.GetResponseStream(), Encoding.UTF8
    );

    /*只取得前 4096 個字*/
    char[] buf = new char[4096];
    stream.Read(buf, 0, buf.Length);

    /*尋找標題字串*/
    string pageText = new String(buf);
    string pattern = @"(?<=<title[^>]*>)([^<]*)(?=</title>)";
    title = Regex.Match(pageText, pattern, RegexOptions.IgnoreCase)
            .Value.Trim();

}catch(WebException e){
}finally{
    if(response!=null){ response.Close(); }
}

title.Dump();
2013-04-04 22:05

PDO fetch 模式的回傳結果

PDO 的 fetch 模式功能實在是太方便了,但每次要產生想要的結果都要試太麻煩了,這裡列出可能的組合。

<?php
$dbAdapter = new PDO("mysql:host=localhost;dbname=test", "root", "1234");
$dbAdapter->exec("SET NAMES 'utf8';");




$data = $dbAdapter->query("
    SELECT id, name, method FROM category
")->fetchAll(PDO::FETCH_ASSOC);

//var_dump($data);
/*
array(
    array(
        'id' => '1',
        'name' => 'HBO',
        'method' => 'service',
    ),
    array(
        'id' => '2',
        'name' => '本週新片',
        'method' => 'movie',
    ),
    array(
        'id' => '3',
        'name' => '熱映中',
        'method' => 'movie',
    ),
)
*/



$data = $dbAdapter->query("
    SELECT name, method FROM category
")->fetchAll(PDO::FETCH_COLUMN);

//var_dump($data);
/*
array(
    'HBO',
    '本週新片',
    '熱映中',
)
*/



$data = $dbAdapter->query("
    SELECT id, name, method FROM category
")->fetchAll(PDO::FETCH_UNIQUE | PDO::FETCH_ASSOC);

//var_dump($data);
/*
array(
    '1' => array(
        'name' => 'HBO',
        'method' => 'service',
    ),
    '2' => array(
        'name' => '本週新片',
        'method' => 'movie',
    ),
    '3' => array(
        'name' => '熱映中',
        'method' => 'movie',
    ),
)
*/



$data = $dbAdapter->query("
    SELECT method, id, name FROM category
")->fetchAll(PDO::FETCH_UNIQUE | PDO::FETCH_ASSOC);

//var_dump($data);
/*
array(
    'service' => array(
        'id' => '1',
        'name' => 'HBO',
    ),
    'movie' => array(
        'id' => '3',
        'name' => '熱映中',
    ),
)
*/



$data = $dbAdapter->query("
    SELECT id, name, method FROM category
")->fetchAll(PDO::FETCH_UNIQUE | PDO::FETCH_COLUMN);

//var_dump($data);
/*
array(
    '1' => 'HBO',
    '2' => '本週新片',
    '3' => '熱映中',
)
*/



$data = $dbAdapter->query("
    SELECT method, name, id FROM category
")->fetchAll(PDO::FETCH_UNIQUE | PDO::FETCH_COLUMN);

//var_dump($data);
/*
array(
    'service' => 'HBO',
    'movie' => '熱映中',
)
*/




$data = $dbAdapter->query("
    SELECT method, id, name FROM category
")->fetchAll( PDO::FETCH_ASSOC | PDO::FETCH_GROUP);

//var_dump($data);
/*
array(
    'service' => array(
        array(
            'id' => '1'
            'name' => 'HBO'
        ),
    )
    'movie' => array(
        array(
          'id' => '2'
          'name' => '本週新片'
        ),
        array(
          'id' => '3'
          'name' => '熱映中'
        ),
    )
)
*/




$data = $dbAdapter->query("
    SELECT method, name, id FROM category
")->fetchAll(PDO::FETCH_GROUP | PDO::FETCH_COLUMN);

//var_dump($data);
/*
array(
    'service' => array(
        'HBO'
    ),
    'movie' => array(
        '本週新片'
        '熱映中'
    ),
)
*/





$data = $dbAdapter->query("
    SELECT id, name, method FROM category
")->fetchAll(PDO::FETCH_OBJ);

//var_dump($data);
/*
array(
    stdClass{
        public $id = '1';
        public $name = 'HBO';
        public $method = 'service';
    },
    stdClass{
        public $id = '2';
        public $name = '本週新片';
        public $method = 'movie';
    },
    stdClass{
        public $id = '3';
        public $name = '熱映中';
        public $method = 'movie';
    },
)
*/







class Category_1 {}

$data = $dbAdapter->query("
    SELECT id, name, method FROM category
")->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "Category_1");

//var_dump($data);
/*
array(
    Category_1{
        public $id = '1';
        public $name = 'HBO';
        public $method = 'service';
    },
    Category_1{
        public $id = '2';
        public $name = '本週新片';
        public $method = 'movie';
    },
    Category_1{
        public $id = '3';
        public $name = '熱映中';
        public $method = 'movie';
    },
),
*/





class Category_2 {
    public $name;
    public $method;

    public function __construct() {}
    public function __set($name, $value ){}
}

$data = $dbAdapter->query("
    SELECT id, name, method FROM category
")->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "Category_2");

//var_dump($data);
/*
array(
    Category_2{
        public $name = 'HBO';
        public $method = 'service';
    },
    Category_2{
        public $name = '本週新片';
        public $method = 'movie';
    },
    Category_2{
        public $name = '熱映中';
        public $method = 'movie';
    },
)
*/
2013-02-26 08:37

[JSX] 串接圖片

由於工作上的需要將圖片分類串接成好幾組圖片,所以寫了一個 PhotoShop Scripting 來完成這件事。

圖片名稱是:
a001-01.jpg
a001-02.jpg
a002-01.jpg
a002-02.jpg
b001-01.jpg
b001-02.jpg
b001-03.jpg

而希望可以依 a001.jpg, a002.jpg, b001.jpg 分類串接在一起。

執行方式:
  1. 檔案 -> 指令碼 -> 瀏覽 -> 選擇 photo_join.jsx
  2. 在選擇多張要串接的圖片

/** 圖片串接 for (PhotoShop Script)
 *  author : Jax
 *  email : weskerjax[at]gmail.com
 *  website : http://jax-work-archive.blogspot.com/
 *  history : 2013.02.23
 */
// photo_join.jsx
//#target photoshop


/**水平邊界px*/
var levMargin = 10;

/**垂直邊界px*/
var verMargin = 10;

var WebJpegOptions = new ExportOptionsSaveForWeb()
WebJpegOptions.format = SaveDocumentType.JPEG;
WebJpegOptions.quality=80;

function main(){
    /*取得多個的檔案路徑*/
    var fileList = File.openDialog(
        "開啟 JPG 檔案",
        "JPG Files:*.jpg",
        true
    );
    if(fileList.length == 0){ alert("沒有任何檔案"); return; }

    /*依檔名排序*/
    fileList.sort();

    /*檔案依前綴分群*/
    var groupList = {};
    var filePath, i=0;
    while(filePath=fileList[i++]){
        var prefix=filePath.name.match(/([a-z0-9]+)[-_].+\.jpg/i);
        if(!prefix || !prefix[1]){continue;}
        if(!groupList[prefix[1]]){ groupList[prefix[1]]=[]; }
        groupList[prefix[1]].push(filePath);
    }

    /*依分群串接圖片*/
    for(prefix in groupList){
        photoJoin(prefix,groupList[prefix]);
    }
}


function copyArt(toArt, fromArt){
    /*複製圖層*/
    app.activeDocument=fromArt;
    fromArt.selection.selectAll()
    fromArt.selection.copy()

    /*貼上圖層*/
    app.activeDocument=toArt;
    return toArt.paste();
}


function photoJoin(prefix, fileList){
    /*新增目標圖片文件*/
    var newPic = app.documents.add(
        1, 1, 72,
        prefix,
        NewDocumentMode.RGB,
        DocumentFill.TRANSPARENT
    );

    workSpace=fileList[0].parent.fsName.replace(/\\/ig,'/');;

    var height=0;
    var width = newPic.width;
    var correspond = [];

    /*複製所有圖檔至新建立的圖檔*/
    for (var i=0; i<fileList.length; i++){
        try {
            var atDoc=open(new File(fileList[i]));
        } catch (e) { continue; }

        /*累計高度*/
        height += atDoc.height.value + verMargin;
        /*最大寬度*/
        width = Math.max(width,atDoc.width);

        /*複製圖層*/
        var layer = copyArt(newPic, atDoc);
        correspond.push({
            'layer':layer,
            'height':atDoc.height.value
        });

        /*關閉檔案*/
        atDoc.close(SaveOptions.DONOTSAVECHANGES);
    };

    app.activeDocument=newPic;

    /*變更圖片大小*/
    newPic.resizeCanvas(
        width+levMargin*2,
        height+verMargin,
        AnchorPosition.TOPLEFT
    );

    /*變更圖層定位*/
    var top=verMargin;
    for (var i=0,l=correspond.length; i<l; i++){
        if(correspond[i].layer===undefined){continue;}

        correspond[i].layer.translate(levMargin, top); /*移動圖層*/
        top += correspond[i].height+verMargin; /*定位累計*/
    };

    /*匯出網頁JPEG*/
    newPic.exportDocument(
        new File(File.encode(workSpace+"/"+prefix+".jpg")),
        ExportType.SAVEFORWEB,
        WebJpegOptions
    );

    /*關閉 newArt 文件*/
    newPic.close(SaveOptions.DONOTSAVECHANGES);
}

/*把Photoshop推到最上層*/
app.bringToFront();
/*設定使用的單位為「像素(Pixel)」*/
app.preferences.rulerUnits = Units.PIXELS;
/*執行主程式*/
main();

alert('成功執行!');


2012-09-30 22:24

[轉載][PHP] preg_replace 效能測試 (將兩個空白字元以上取代成一個)

轉載自:[PHP] preg_replace 效能測試 (將兩個空白字元以上取代成一個) 小惡魔 – 電腦技術 – 工作筆記 – AppleBOY

preg_replace 可以使用正規語法來取代字串任何字元,,今天探討取代空白字元的效能,雖然這是個不起眼的效能評估,一般人不太會這樣去改,不過這是國外 PHP Framework 有人提出來修正的,經過許多人的測試一致同意。功能就是一篇文章內如果有多餘的空白能空取代成一個,一般人都會用 \s+ 正規語法,畢竟大家都知道 \s 代表單一空白或 \r 等符號,但是國外有人提出用 {2,} 方式來取代空白。程式碼如下,大家可以測試看看。

<?php
$nb = 10000;
$str = str_repeat('Hi, I am appleboy  ' . "\n", 10);
$t1 = microtime(true);
for ($i = $nb; $i--; ) {
    preg_replace('/\s+/', ' ', $str);
}
$t2 = microtime(true);
for ($i = $nb; $i--; ) {
    preg_replace('/ {2,}/', ' ', 
        str_replace(array("\r","\n","\t","\x0B","\x0C"),' ',$str)
    );
}
$t3 = microtime(true);

echo $t2 - $t1;
echo "\n";
echo $t3 - $t2;

測試結果(1萬次)

PHP 5.3.3
old: 0.13053798675537
new: 0.058536052703857

PHP 5.3.15
old: 0.11732506752014
new: 0.071418046951294

PHP 5.3.17
old: 0.11612010002136
new: 0.07065486907959

PHP 5.4.5
old: 0.1185781955719
new: 0.066012859344482

PHP 5.4.7
old: 0.11343121528625
new: 0.066931962966919

結論至少快蠻多的,如果整體資料量再大一點,我想差別會更大,那至於要不要用呢,就看個人了 XD。
2012-09-05 13:32

Apache 消失的 ServerLimit 參數

在某些版本的 Apache 中如果單純加大 MaxClients 的設定值,就會得到以下的錯誤訊息:
WARNING: MaxClients of 300 exceeds ServerLimit value of 256 servers,
  lowering MaxClients to 256. To increase, please see the ServerLimit
  directive.

這時必須再增加 ServerLimit 這個設定,而這個設定在設定檔中並沒有提示,所以需要額外加入。
<IfModule mpm_prefork_module>
    ServerLimit         500 # 額外加入
    StartServers         10
    MinSpareServers      10
    MaxSpareServers      20
    MaxClients          300
    MaxRequestsPerChild   0
</IfModule>

停止並啟動(單純 restart 無法套用設定)
service apache2 stop
service apache2 start

參考來源:
Gilbert.tw > Apache 之謎樣 ServerLimit 指令 (directive)
2012-09-05 13:01

[Ubuntu] 用 logrotate 定期切割 Apache log 檔

Ubuntu 預設已經為 Apache 建立了 log 分割管理,但在建立虛擬主機(Virtual Host),但又很龜毛的將 log 獨立到個別的子目錄下的話,預設的 logrotate 是沒有辦法處理到的,所以請記得為這龜毛的動作加上額外設定。

編輯屬於 Apache 的設定檔,在檔案最後面加上額外的設定。
vim /etc/logrotate.d/apache2
/var/log/apache2/blog/*.log {
    daily
    missingok
    rotate 52
    dateext
    compress
    delaycompress
    notifempty
    create 640 root adm
    sharedscripts
    postrotate
        /etc/init.d/apache2 reload > /dev/null
    endscript
}

參數說明:
daily 每天整理,其他還有 weekly, monthly, yearly
missingok 允許 log 檔不存在
nomissingok 不允許 log 檔不存在,會丟出錯誤 (預設)
rotate 7 保留 7 次的分割
size 1M 大小超過 1M 就執行分割,單位可以是 1024, 100k, 4M, 1G
dateext 用日期來建立分割檔名,而非流水號
dateformat -%Y%m%d 日期格式
compress 壓縮分割,預設用 gzip (預設)
nocompress 不壓縮分割
delaycompress 延後壓縮直到下一次 rotate
notifempty 如果 log 是空的就不執行
copytruncate 以[複製清空]的方式分割 log,這樣可以用不到 postrotate 設定
mail xxx@address 將分割內容用 mail 寄出
prerotate/endscript 分割前要執行的指令
postrotate/endscript 分割後要執行的指令


測試設定檔是否正確
logrotate -f /etc/logrotate.conf


參考來源:
使用 logrotate 定期整理 Rails Log 檔案
[ubuntu] 使用 logrotate 定期切割壓縮 apache2 的 log 檔
2012-09-05 11:46

[轉載] [MySQL] QueryCache原理

轉載自:PHP 程式 學習 筆記本 [Mysql]QueryCache原理

原理
QueryCache(下面簡稱QC)是根據SQL語句來cache的。一個SQL查詢如果以select開頭,那麼MySQL服務器將嘗試對其使用QC。每個Cache都是以SQL文本作為key來存的。在應用QC之前,SQL文本不會被作任何處理。也就是說,兩個SQL語句,只要相差哪怕是一個字符(例如大小寫不一樣;多一個空格等),那麼這兩個SQL將使用不同的一個CACHE。

不過SQL文本有可能會被客戶端做一些處理。例如在官方的命令行客戶端裡,在發送SQL給服務器之前,會做如下處理:
  • 過濾所有註釋
  • 去掉SQL文本前後的空格,TAB等字符。注意,是文本前面和後面的。中間的不會被去掉。


下面的三條SQL裡,因為SELECT大小寫的關係,最後一條和其他兩條在QC裡肯定是用的不一樣的存儲位置。而第一條和第二條,區別在於後者有個註釋,在不同客戶端,會有不一樣的結果。所以,保險起見,請儘量不要使用動態的註釋。在PHP的mysql擴展裡,SQL的註釋是不會被去掉的。也就是三條SQL會被存儲在三個不同的緩存裡,雖然它們的結果都是一樣的
SELECT * FROM people where name='surfchen';
SELECT * FROM people where /*hey~*/name='surfchen';
SELECT * FROM people where name='surfchen';


目前只有select語句會被cache,其他類似show,use的語句則不會被cache。

因為QC是如此前端,如此簡單的一個緩存系統,所以如果一個表被更新,那麼和這個表相關的SQL的所有QC都會被失效。假設一個聯合查詢裡涉及到了表A和表B,如果表A或者表B的其中一個被更新(update或者delete),這個查詢的QC將會失效。

也就是說,如果一個表被頻繁更新,那麼就要考慮清楚究竟是否應該對相關的一些SQL進行QC了。一個被頻繁更新的表如果被應用了QC,可能會加重數據庫的負擔,而不是減輕負擔。我一般的做法是默認打開QC,而對一些涉及頻繁更新的表的SQL語句加上SQL_NO_CACHE關鍵詞來對其禁用CACHE。這樣可以儘可能避免不必要的內存操作,儘可能保持內存的連續性。

那些查詢很分散的SQL語句,也不應該使用QC。例如用來查詢用戶和密碼的語句——「select pass from user where name='surfchen'」。這樣的語句,在一個系統裡,很有可能只在一個用戶登陸的時候被使用。每個用戶的登陸所用到的查詢,都是不一樣的SQL文本,QC在這裡就幾乎不起作用了,因為緩存的數據幾乎是不會被用到的,它們只會在內存裡佔地方。


存儲塊
在本節裡「存儲塊」和「block」是同一個意思
QC緩存一個查詢結果的時候,一般情況下不是一次性地分配足夠多的內存來緩存結果的。而是在查詢結果獲得的過程中,逐塊存儲。當一個存儲塊被填滿之後,一個新的存儲塊將會被創建,並分配內存(allocate)。單個存儲塊的內存分配大小通過query_cache_min_res_unit參數控制,默認為4KB。最後一個存儲塊,如果不能被全部利用,那麼沒使用的內存將會被釋放。如果被緩存的結果很大,那麼會可能會導致分配內存操作太頻繁,系統系能也隨之下降;而如果被緩存的結果都很小,那麼可能會導致內存碎片過多,這些碎片如果太小,就很有可能不能再被分配使用。

除了查詢結果需要存儲塊之外,每個SQL文本也需要一個存儲塊,而涉及到的表也需要一個存儲塊(表的存儲塊是所有線程共享的,每個表只需要一個存儲塊)。存儲塊總數量=查詢結果數量*2+涉及的數據庫表數量。也就是說,第一個緩存生成的時候,至少需要三個存儲塊:表信息存儲塊,SQL文本存儲塊,查詢結果存儲塊。而第二個查詢如果用的是同一個表,那麼最少只需要兩個存儲塊:SQL文本存儲塊,查詢結果存儲塊。

通過觀察Qcache_queries_in_cacheQcache_total_blocks可以知道平均每個緩存結果占用的存儲塊。它們的比例如果接近1:2,則說明當前的query_cache_min_res_unit參數已經足夠大了。如果Qcache_total_blocks比Qcache_queries_in_cache多很多,則需要增加query_cache_min_res_unit的大小。

Qcache_queries_in_cache * query_cache_min_res_unit(sql文本和表信息所在的block佔用的內存很小,可以忽略)如果遠遠大於query_cache_size-Qcache_free_memory,那麼可以嘗試減小query_cache_min_res_unit的值。


調整大小
如果Qcache_lowmem_prunes增長迅速,意味著很多緩存因為內存不夠而被釋放,而不是因為相關表被更新。嘗試加大query_cache_size,儘量使Qcache_lowmem_prunes零增長。


啟動參數
show variables like 'query_cache%' 可以看到這些信息。
query_cache_limit:如果單個查詢結果大於這個值,則不Cache
query_cache_size:分配給QC的內存。如果設為0,則相當于禁用QC。要注意QC必須使用大約40KB來存儲它的結構,如果設定小於40KB,則相當于禁用QC。QC存儲的最小單位是1024 byte,所以如果你設定了一個不是1024的倍數的值,這個值會被四捨五入到最接近當前值的等於1024的倍數的值。
query_cache_type:
0 完全禁止QC,不受SQL語句控制(另外可能要注意的是,即使這裡禁用,上面一個參數所設定的內存大小還是會被分配);
1啟用QC,可以在SQL語句使用SQL_NO_CACHE禁用
2可以在SQL語句使用SQL_CACHE啟用。

query_cache_min_res_unit:每次給QC結果分配內存的大小


狀態
show status like 'Qcache%' 可以看到這些信息。
Qcache_free_blocks:當一個表被更新之後,和它相關的cache blocks將被free。但是這個block依然可能存在隊列中,除非是在隊列的尾部。這些blocks將會被統計到這個值來。可以用FLUSH QUERY CACHE語句來清空free blocks。

其他幾個狀態變量的意義:
Qcache_free_memory 表示查詢緩存區現在還有多少的可用內存,如果很小,考慮增加query_cache_size
Qcache_hits 表示查詢緩存區的命中個數,也就是直接從查詢緩存區作出響應處理的查詢個數
Qcache_inserts 表示查詢緩存區此前總過緩存過多少條查詢命令的結果
Qcache_lowmem_prunes 表示查詢緩存區已滿而從其中溢出和刪除的查詢結果的個數
Qcache_not_cached 自mysql進程啟動起,沒有被cache的只讀查詢數量(包括select,show,use,desc等)
Qcache_queries_in_cache 當前被cache的SQL數量
Qcache_total_blocks:在QC中的blocks數。一個query可能被多個blocks存儲,而這幾個blocks中的最後一個,未用滿的內存將會被釋放掉。例如一個QC結果要佔6KB內存,如果query_cache_min_res_unit是4KB,則最後將會生成3個blocks,第一個block用來存儲sql語句文本,這個不會被統計到query+cache_size裡,第二個block為4KB,第三個block為2KB(先allocate4KB,然後釋放多餘的2KB)。每個表,當第一個和它有關的SQL查詢被CACHE的時候,會使用一個block來存儲表信息。也就是說,block會被用在三處地方:表信息,SQL文本,查詢結果。

優化提示:如果Qcache_lowmem_prunes 值比較大,表示查詢緩存區大小設置太小,需要增大。如果Qcache_free_blocks 較多,表示內存碎片較多,需要清理,flush query cache

根據我看的 《High Performance MySQL》中所述,關於query_cache_min_res_unit大小的調優,書中給出了一個計算公式,可以供調優設置參考:
query_cache_min_res_unit = (query_cache_size - Qcache_free_memory) / Qcache_queries_in_cache

還要注意一點的是,FLUSH QUERY CACHE 命令可以用來整理查詢緩存區的碎片,改善內存使用狀況,但不會清理查詢緩存區的內容,這個要和RESET QUERY CACHE相區別,不要混淆,後者才是清除查詢緩存區中
的所有的內容。