0

ロード時に、150,000,000 行のテーブルに対して 10 の異なるクエリを実行する Web サイト ページがあります。

通常、ページは 2 秒未満で読み込まれますが、頻繁に更新すると多くのクエリが作成され、ページの読み込み時間が最大 10 秒遅くなります。

これらのクエリをすべて実行しないようにするにはどうすればよいですか? データベースが停止してしまうからです。

私はまだキャッシュを持っていません。サイトは次のように機能します。すべての URI が格納されているテーブルがあります。ユーザーが URL を入力すると、呼び出された URL から URI を取得し、URI が格納されているかどうかをテーブルにチェックインします。URI がテーブルに格納されている場合は、リレーショナル データベースの他のテーブルから対応するデータを取得します。

他のテーブルから情報を取得する PHP ファイルの 1 つからのサンプル コードは次のとおりです。

<?php
set_time_limit(2);
define('MODX_CORE_PATH', '/path/to/modx/core/');
define('MODX_CONFIG_KEY','config');
require_once MODX_CORE_PATH . 'model/modx/modx.class.php';

// Criteria for foreign Database
$host = 'hostname';
$username = 'user';
$password = 'password';
$dbname = 'database';
$port = 3306;
$charset = 'utf8mb4';

$dsn = "mysql:host=$host;dbname=$dbname;port=$port;charset=$charset";
$xpdo = new xPDO($dsn, $username, $password);

// Catch the URI that is called
$pageURI = $_SERVER["REQUEST_URI"];

// Get the language token saved as TV "area" in parent and remove it
if (!isset($modx)) return '';

$top = isset($top) && intval($top) ? $top : 0;
$id= isset($id) && intval($id) ? intval($id) : $modx->resource->get('id');
$topLevel= isset($topLevel) && intval($topLevel) ? intval($topLevel) : 0;
if ($id && $id != $top) {
    $pid = $id;
    $pids = $modx->getParentIds($id);
    if (!$topLevel || count($pids) >= $topLevel) {
        while ($parentIds= $modx->getParentIds($id, 1)) {
            $pid = array_pop($parentIds);
            if ($pid == $top) {
                break;
            }
            $id = $pid;
            $parentIds = $modx->getParentIds($id);
            if ($topLevel && count($parentIds) < $topLevel) {
                break;
            }
        }
    }
}
$parentid = $modx->getObject('modResource', $id);
$area = "/".$parentid->getTVValue('area');
$URL = str_replace($area, '', $pageURI);
$lang= $parentid->getTVValue('lang');

// Issue queries against the foreign database:
$output = '';
$sql = "SELECT epf_application_detail.description FROM epf_application_detail INNER JOIN app_uri ON epf_application_detail.application_id=app_uri.application_id WHERE app_uri.uri = '$URL' AND epf_application_detail.language_code = '$lang'";
foreach ($xpdo->query($sql) as $row) {
    $output .= nl2br($row['description']);
}
return $output;
4

2 に答える 2

1

使用している言語がわからない場合は、ここにいくつかの疑似コードを示します。

ページが読み込まれるたびに大きなクエリを実行する代わりに、「キャッシュ」などと呼ばれる別のテーブルを作成できます。クエリを実行し、クエリからのデータをそのキャッシュ テーブルに格納できます。次に、ページが読み込まれると、キャッシュ テーブルにクエリを実行できます。キャッシュ テーブルははるかに小さくなり、ページを頻繁に更新しても問題が発生することはありません。

疑似コード (キャッシュを最新の状態に保つために、cronjob などを使用して一定間隔で実行できます):

10 個の大規模なクエリを実行します。クエリごとに、次のcacheように結果を追加します。

query_id  |  query_data
----------------------------------------------------
      1   |  {whatever your query data looks like}

次に、ページが読み込まれると、各クエリでデータを収集します。cache

キャッシュ テーブルを使用すると、頻繁に更新する必要があることに注意してください。(より多くのデータを取得するたびに、または5分ごとなどの設定された間隔で。)

于 2013-07-09T14:21:13.830 に答える