1

Mysql サーバーはキャッシュするように設定されています。

query_cache_size = 1G
query_cache_type = 1

phpmyadmin からクエリを実行すると、最初にクエリに 2 秒、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

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. word_full (INT UNSIGNED AUTO_INCREMENT NOT NULL) に wordID 列を追加し、それを主キーにします
  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 にキーを追加します

単語を数値キーから外れるように変更すると、MySQL はインデックスをはるかに効率的に使用できるようになります。現在(私は推測しています)、varchar 列を 2 回結合してから、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 に答える