簡體   English   中英

有效地使用mysql表來緩存復雜的查詢

[英]Efficiently use mysql Table to cache complex queries

我曾經在查詢中有相當多的多個連接。

為了能夠使用(至少)內置的MySql Cache功能,我編寫了以下函數,它只是將原始查詢編碼到base64中,檢查它是否存在且未過期。

這大大提高了性能,並且我有利於在源代碼中控制查詢的緩存時間。

但是在繁忙的時候,由於刪除或者選擇只是花費太長時間,表格變得不可用。 有什么建議可以使這個運行更快並避免前面提到的問題嗎?

表:

CREATE TABLE `cachesql` (
`id` int(9) NOT NULL AUTO_INCREMENT,
`expire` int(15) NOT NULL,
`sql` text NOT NULL,
`data` mediumtext NOT NULL,
PRIMARY KEY (`id`,`sql`(360)),
KEY `sdata` (`sql`(767)) USING HASH
) ENGINE=InnoDB

功能:

    function fetchRows_cache($sql,$cachetime,$dba){
    // internal function (called by fetchRows)
    global $Site;
    $expire = 0;
    $this->connect($dba);

    // check if query is cached
    $this->q = mysql_query("SELECT `expire`,`data` from cachesql where `sql`='".base64_encode($sql)."' limit 1;", $this->con) OR $this->error(1, "query$".$sql."$".mysql_error());
    $this->r = mysql_fetch_assoc($this->q);
    $expire = $this->r['expire'];
    $data = $this->r['data'];

    if (($expire < time())||($cachetime =="0")) { // record expied or not there -> execute query and store
        $this->query("DELETE FROM `cachesql` WHERE `sql`='".base64_encode($sql)."'",$dba); // delete old cached entries

        $this->q = mysql_query($sql, $this->con) OR $this->error(1, "query$".$sql."$".mysql_error());
        $this->r=array();
        $this->rc=0;
        while($row = mysql_fetch_assoc($this->q)){
            $arr_row=array();
            $c=0;
            while ($c < mysql_num_fields($this->q)) {        
                $col = mysql_fetch_field($this->q, $c);    
                $arr_row[$col -> name] = $row[$col -> name];            
                $c++;
            }    
            $this->r[$this->rc] = $arr_row;
            $this->rc++;
        }
        $out = $this->r;

        // write results into cache table
        if ($cachetime != "0") {
            // not store cache values for now (too many locks)
            $this->query("INSERT INTO `cachesql` (`sql`,`data`,`expire`) VALUES ('".base64_encode($sql)."','".mysql_real_escape_string(serialize($out))."','".(time()+$cachetime)."')",$dba);       
        }
        return $out;

    }
    else { // use Cached data
        return unserialize($data); 
    }
}

我認為主要的減速點是,你使用InnoDB作為你的緩存表。

我發現,你應該使用InnoDB除了重讀緩存表之外的一切;)

MyISAM特別適用於讀密集(選擇)表。

感謝@HeatfanJohn--他精心設計了一些簡單而有效的東西。

由於原始查詢不用於任何事情(除了高速緩存條目的匹配),因此只需存儲校驗和就可以唯一地識別有問題的查詢。

新結構只存儲原始查詢(16字節),expireUnixTime和序列化行集的MD5哈希值

新結構:

CREATE TABLE `cachesql` (
`sql` varchar(32) NOT NULL,
`expire` int(11) NOT NULL,
`data` text NOT NULL,
PRIMARY KEY (`sql`),
UNIQUE KEY `sql` (`sql`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='cache for db->fetchRows'

sql列上的主索引響應非常快,因為它非常短,並且可以更好地為搜索索引。

我沒有得到不同的速度結果使用BLOB或TEXT字段的數據集。

讓我們嘗試使用內存表來加快速度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM