1

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;
4

3 回答 3

2

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

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

于 2013-04-19T11:50:21.547 回答
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 。

查询大小 > query_cache_limit

我将 query_cache_limit 增加到 10M。

于 2013-04-22T07:07:50.800 回答
0

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

我会

  1. 将 wordID 列添加到 word_full (INT UNSIGNED AUTO_INCREMENT NOT NULL) 并使其成为主键
  2. 在 word_full.word 上添加唯一键
  3. 将 word_base 更改为引用 wordID(所以现在 wordID 和 word_base 都是数字)
  4. 向 word_full.word_base 添加一个键
  5. 将 search_index.word 更改为 search_index.wordID
  6. 向 search_index.wordID 添加一个键

更改单词以使用数字键将允许 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
于 2013-04-19T11:58:49.393 回答