来自php的SQL查询不使用mysql缓存

时间:2013-04-19 11:47:46

标签: php mysql caching

Mysql服务器设置为缓存:

query_cache_size = 1G
query_cache_type = 1

当我从phpmyadmin执行查询时,第一次查询需要2秒,第二次执行0.0001秒。

因此缓存确实有效。但是在php脚本中,查询每次都会持续2秒。

php version 5.4.14
mysql 5.5.30

脚本:

<?php
    $db = new mysqli("localhost", "user", "pass", "search");
    $t = microtime(true);
    $res = $db-> query("SELECT 
                            i.page_id, 
                            SUM(i.weight) as w 
                        FROM
                            search.search_index i 
                        INNER JOIN 
                            search.word_full w1 
                            ON w1.word=i.word 
                        INNER JOIN 
                            search.word_full w2 
                            ON w1.word_base=w2.word_base 
                        WHERE 
                            w2.word = 'api' 
                        GROUP BY 
                            i.page_id 
                        ORDER BY NULL");
    print($res->num_rows."\n");
    print(microtime(true) - $t);
?>

<?php
    $link = mysql_connect("localhost", "root", "pass");
    mysql_select_db("search");

    $t = microtime(true);
    $res = $db-> query("SELECT 
                            i.page_id, 
                            SUM(i.weight) as w 
                        FROM
                            search.search_index i 
                        INNER JOIN 
                            search.word_full w1 
                            ON w1.word=i.word 
                        INNER JOIN 
                            search.word_full w2 
                            ON w1.word_base=w2.word_base 
                        WHERE 
                            w2.word = 'api' 
                        GROUP BY 
                            i.page_id 
                        ORDER BY NULL");
    print(mysql_num_rows($res)."\n");
    print(microtime(true) - $t);
?>

如果我试试这个:     

    $t = microtime(true);
    $res = $db-> query("SELECT 
                            i.page_id, 
                            SUM(i.weight) as w 
                        FROM
                            search.search_index i 
                        INNER JOIN 
                            search.word_full w1 
                            ON w1.word=i.word 
                        INNER JOIN 
                            search.word_full w2 
                            ON w1.word_base=w2.word_base 
                        WHERE 
                            w2.word = 'api' 
                        GROUP BY 
                            i.page_id 
                        ORDER BY NULL");
    print(mysql_num_rows($res)."\n");
    print(microtime(true) - $t."\n");

    $t = microtime(true);
    $res = $db-> query("SELECT 
                            i.page_id, 
                            SUM(i.weight) as w 
                        FROM
                            search.search_index i 
                        INNER JOIN 
                            search.word_full w1 
                            ON w1.word=i.word 
                        INNER JOIN 
                            search.word_full w2 
                            ON w1.word_base=w2.word_base 
                        WHERE 
                            w2.word = 'api' 
                        GROUP BY 
                            i.page_id 
                        ORDER BY NULL");
    print(mysql_num_rows($res)."\n");
    print(microtime(true) - $t."\n");
?>

脚本返回

235899
1.8554458618164
235899
1.8542320728302

Mysql缓存也不起作用。

表格结构:

CREATE TABLE IF NOT EXISTS `search_index` (
  `page_id` varchar(32) NOT NULL,
  `word` varchar(32) NOT NULL,
  `weight` int(11) NOT NULL,
  PRIMARY KEY (`word`,`page_id`),
  KEY `page_id` (`page_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;



CREATE TABLE IF NOT EXISTS `word_full` (
  `word` varchar(32) NOT NULL,
  `word_base` varchar(32) NOT NULL,
  PRIMARY KEY (`word`,`word_base`),
  UNIQUE KEY `word_base` (`word_base`,`word`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3 个答案:

答案 0 :(得分:2)

PHP中的每个调用都是一个新实例,与前一个实例无关。除非你明确声明它。

查看查询缓存:http://php.net/manual/en/mysqlnd-qc.quickstart.caching.php

答案 1 :(得分:0)

我假设word_full.word_baseword_full.word都是VARCHAR列。如果不是这种情况,请提供完整的表结构,包括search_index和word_full表的键。

我会

  1. 将wordID列添加到word_full(INT UNSIGNED AUTO_INCREMENT NOT NULL)并将其设为主要KEy
  2. 在word_full.word上添加一个UNIQUE键
  3. 将word_base更改为引用wordID(现在wordID和word_base都是数字)
  4. 为word_full.word_base添加密钥
  5. 将search_index.word更改为search_index.wordID
  6. 为search_index.wordID
  7. 添加密钥

    更改单词以运行数字键将允许MySQL更有效地使用索引。目前(我假设)您将加入一个varchar列两次,然后搜索varchar列。这是非常低效的。

    最后,将WHERE移动到JOIN中可能会允许它在不同的点减少行,因此有效地更加优化。这给出了

    的最终查询
    SELECT 
        i.page_id, 
        SUM(i.weight) as w 
    
    FROM search.search_index i 
    
    INNER JOIN search.word_full w1 
        ON w1.wordID = i.wordID
    
    INNER JOIN search.word_full w2 
        ON w1.wordID_base = w2.wordID_base 
        AND w2.word = 'api' 
    
    GROUP BY i.page_id 
    ORDER BY NULL
    

答案 2 :(得分:0)

phpmyadmin修改查询

SELECT 
    i.page_id, 
    SUM(i.weight) as w 
FROM
    search.search_index i 
INNER JOIN 
    search.word_full w1 
    ON w1.word=i.word 
INNER JOIN 
    search.word_full w2 
    ON w1.word_base=w2.word_base 
WHERE 
    w2.word = 'api' 
GROUP BY 
    i.page_id 
ORDER BY NULL

SELECT 
    i.page_id, 
    SUM(i.weight) as w 
FROM
    search.search_index i 
INNER JOIN 
    search.word_full w1 
    ON w1.word=i.word 
INNER JOIN 
    search.word_full w2 
    ON w1.word_base=w2.word_base 
WHERE 
    w2.word = 'api' 
GROUP BY 
    i.page_id 
ORDER BY NULL
LIMIT 0, 30

在查询结束时添加 LIMIT 0,30

查询大小&gt; query_cache_limit

我将query_cache_limit增加到10M。