1

私は学校の VLE 用にかなり壊れやすい PHP/JavaScript 報酬システムを開発しました。

作業の大部分はtransactions、次のフィールドを持つテーブルで行われます。

Transaction_ID, Datetime, Giver_ID, Recipient_ID, Points, Category_ID_Reason

私がスタッフの一員として学生に報酬ポイントを与えると、次のようなエントリがデータベースに挿入されます。

INSERT INTO `transactions` (`Transaction_ID`, `Datetime`, `Giver_ID`, `Recipient_ID`, `Points`, `Category_ID`, `Reason`) VALUES
(60332, '2012-02-22', 34985, 137426, 5, 5, 'Excellent volcano homework.');

これは問題なく機能しましたが、システムがどれだけ使用されるかはあまり考えていませんでした。現在、このテーブルには72,000 を超えるトランザクションがあります。

そのため、私のページのいくつかが遅くなり始めています。たとえば、スタッフがポイントを割り当てようとすると、私のシステムはコマンドを実行して、スタッフの合計ポイント割り当てとその他の情報の断片を取得します。これはかなりゆっくりと表示されているように見えます.MySQLステートメント/付随するPHPコードを見ると、これははるかに効率的であると思います.

function getLimitsAndTotals($User_ID) {

    $return["SpentTotal"] = 0;
    $return["SpentWeekly"] = 0;

    $sql = "SELECT * 
        FROM `transactions` 
        WHERE `Giver_ID` =$User_ID";
    $res = mysql_query($sql);

    if (mysql_num_rows($res) > 0) {
        while ($row = mysql_fetch_assoc($res)) {
            $return["SpentTotal"] += $row["Points"];

            $transaction_date = strtotime ($row["Datetime"]);

            if ($transaction_date > strtotime( "last sunday" )) {
                $return["SpentWeekly"] += $row["Points"];
            }
        }
    }

    return $return;
}

そのため、私の質問は 2 つあります。

  1. この特定のコードを最適化できますか?
  2. システムをさらに最適化するために、データベース技術 (全文索引付けなど) を使用できますか?

編集:REインデックス作成

インデックス作成については何も知りませんが、transactionsテーブルに実際にインデックスが設定されているように見えますか?

トランザクション テーブル インデックス

これは正しいタイプのインデックスですか?

テーブル作成のコードは次のとおりです。

CREATE TABLE IF NOT EXISTS `transactions` (
  `Transaction_ID` int(9) NOT NULL auto_increment,
  `Datetime` date NOT NULL,
  `Giver_ID` int(9) NOT NULL,
  `Recipient_ID` int(9) NOT NULL,
  `Points` int(4) NOT NULL,
  `Category_ID` int(3) NOT NULL,
  `Reason` text NOT NULL,
  PRIMARY KEY  (`Transaction_ID`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=74927 ;

前もって感謝します、

4

3 に答える 3

1

インデックスGiver_IDが作成されていることを確認してください。72,000回実行するのは高価な操作だと思うので、whileループの外でstrtotimeも実行してみてください。

if (mysql_num_rows($res) > 0) {

    // assign the unix timestamp of last sunday here.
    $last_sunday = strtotime('last sunday');

    while ($row = mysql_fetch_assoc($res)) {
        $return["SpentTotal"] += $row["Points"];

        $transaction_date = strtotime ($row["Datetime"]);

        if ($transaction_date > $last_sunday) {
            $return["SpentWeekly"] += $row["Points"];
        }
    }
}

またUNIX_TIMESTAMP(Datetime) AS datetime_timestamp、文字列として取得して別の高価な strtotime 操作を実行する代わりに、SQL で実行することを検討してください。その後、次を実行するだけです。

if (mysql_num_rows($res) > 0) {

    // assign the unix timestamp of last sunday here.
    $last_sunday = strtotime('last sunday');

    while ($row = mysql_fetch_assoc($res)) {
        $return["SpentTotal"] += $row["Points"];

        if ($row['datetime_timestamp'] > $last_sunday) {
            $return["SpentWeekly"] += $row["Points"];
        }
    }
}

(もちろん、列のタイプが DATE の場合です!)

于 2012-04-25T12:50:49.093 に答える
0

この特定のコードを最適化できますか?

はい。
しかし、「コードを見る」ことでは絶対にありません。

システムをさらに最適化するために、データベース技術 (全文索引付けなど) を使用できますか?

いいえ、できません。システムで確実に何が遅いのかがわからないという理由
だけで。

これは日常生活では誰にでも広く使われている常識ですが、Web サイトをプログラミングし始めると、なぜか完全に忘れ去られてしまいます。

あなたの質問は、「私の車が遅くなってきています。どうすれば速くなりますか?」というようなものです。遅さの理由を知らずに、地球上で誰がそれに答えることができますか? タイヤですか?それともガソリン?それとも、周りに道路はなく、原っぱですか?それとも誰かがハンドブレーキを解除するのを忘れただけですか?

最初に速度低下の理由を特定する必要があります。

質問をする前に、クエリの実行時間を測定する必要があります。
それでも速い場合は、サイトの遅さを責めるべきではありません。
そしてプロファイリングを開始します。

まず、ページ全体のどの部分が読み込みを遅くしているのかを判断する必要があります。サードパーティのサーバーから読み込まれる Javascript の一部である可能性があります。
そこで、Firebug の「Net」タブから始めて、最も遅い部分を確認します。

それからそれに進みます。
それがあなたのPHPコードである場合 -microtime(1);問題のある部分を見つけるためにさまざまな部分を測定するために使用してください。

それから質問に来てください。

ただし、質問を速度の最適化の要求としてではなく、SQL の正気度を高めるための要求と見なすと、改善できる点がいくつかあります。

両方の数値を単一の値として取得できます。

select sum(Points) as Total from FROM `transactions` WHERE Giver_ID=$User_ID

あなたにタイトルポイントを与える
だけでなく、

$sunday = date("Y-m-d",strtotime('last sunday'));

select sum(Points) as Spent from FROM `transactions` 
WHERE Giver_ID=$User_ID AND Datetime > '$sunday'

週間ポイントを付与します。

于 2012-04-25T13:19:08.717 に答える
0

72kは何もありません...ただし、mysql構成(サービスに割り当てたメモリの量)やその他のいくつか(mysqlの最適化を検索してください)など、速度低下を引き起こしている他のものがある可能性があります。

またINSERTS、特定のページにいくつあるのかを調べてください。通常、ページの読み込みが遅くなります。ユーザーに対してすべてのアクションを挿入している場合、コストのかかるトランザクションを行っています。

通常、SELECT は INSERT などよりもはるかに安価です。

SQL コードから、次のようなクエリを最適化していないと推測できます。

$sql = "SELECT * 
    FROM `transactions` 
    WHERE `Giver_ID` =$User_ID";

次のようにする必要があります。

$sql = "SELECT Points, DateTime FROM ..."

(データからの大きな問題ではありませんが、必要なもののみを要求し、反復中により多くのメモリを必要とするすべてのものではありません)。

また、スキーマがどのように設計されているかわかりませんが、インデックスを使用していTransaction_IDますか?

于 2012-04-25T12:50:49.913 に答える