3

1 つのコードベースから複数の Web サイトを実行する Web アプリケーションがあります。アプリケーションで実行されるサイトとドメインを含むテーブルをセットアップしました。このアプリケーションは訪問者を追跡するため、サイトごとに、アプリケーションのグローバル ベースでどれだけのトラフィックを獲得しているかがわかります。

私が直面している問題は、そこに 250 万件のレコードがあるため、訪問者の追跡が非常に遅いことです。今月の訪問者数を取得するためのクエリを実行すると数分かかるため、データにあまりアクセスできません。

システムは、他のすべてのファイルを含むベース php ファイルから直接追跡を記録しています。既存の識別 Cookie が見つからない場合、訪問者テーブルにレコードを作成します。レコードを作成するときに、ユーザーに Cookie を割り当てて、ユーザーが戻ってきたときに単一の訪問者レコードのみを作成するようにします。その訪問者レコードには、閲覧したページの数と、閲覧したページ (開始ページ) と最後に閲覧したページ (終了ページ) が保存されます。

かなりの量のトラフィックが得られます。結果を高速化して、この毎月の訪問者レポートをアクセスしやすくしたいと考えています。

以前、site_id と日付にインデックスを追加しようとしましたが、あまり高速化には役立たなかったようです...

Google アナリティクスなどのツールを使用する代わりに、自分でアナリティクスを追跡することにしました。これにより、後でより意味のあるデータを作成できるようになります。サイトを閲覧しているユーザーが連絡先フォームを送信して CRM の連絡先になった場合など、サポートを求める前にその連絡先の履歴を確認して、どのページを閲覧したかを確認したいと考えています。

助言がありますか?テーブル スキーマは次のとおりです。解決策を考え出そうと頭を壁にぶつけてきました。

CREATE TABLE `analytics_track_visits` (
    `id` bigint unsigned NOT NULL AUTO_INCREMENT
    ,`site_id` int(4) unsigned default NULL

    ,`inc` bigint unsigned default NULL
    ,`referer` text NOT NULL
    ,`refer_host` text NOT NULL
    ,`user_agent` text NOT NULL
    ,`browser` text NOT NULL
    ,`os` text NOT NULL
    ,`search_term` text NOT NULL

    ,`entry_page` int(4) unsigned default NULL
    ,`entry_page_url` text default NULL
    ,`exit_page` int(4) unsigned default NULL
    ,`exit_page_url` text default NULL

    ,`created` datetime NOT NULL
    ,`created_ip` varchar(200) NOT NULL default ''
    ,`created_user_id` int(4) unsigned default NULL
    ,`modified` datetime NOT NULL default '0000-00-00'
    ,`modified_user_id` int(4) unsigned default NULL

    ,PRIMARY KEY(`id`)
    ,CONSTRAINT `analytics_track_visits__site` FOREIGN KEY (`site_id`) 
        REFERENCES `site` (`id`) ON DELETE CASCADE
    ,CONSTRAINT `analytics_track_visits__entry_page` FOREIGN KEY (`entry_page`) 
        REFERENCES `page` (`id`) ON DELETE CASCADE
    ,CONSTRAINT `analytics_track_visits__exit_page` FOREIGN KEY (`exit_page`) 
        REFERENCES `page` (`id`) ON DELETE CASCADE
) ENGINE=INNODB;

incその特定の訪問者が閲覧したページ数を保存します。entry_pagecms ページ テーブルへの外部キーです ( exit_page と同じ)。から解釈された値browserを保持します。エントリーページを見つけるために使用されたキーワードを保存します。ドメイン名を含むサイト設定のリストを含むテーブルに関連しています。osuser_agentsearch_termsite_id

問題の一部は、テーブルが実際には壊れないことにあるのではないかと疑っています。そのため、レポートを実行すると、このテーブルを同時に挿入および更新するアクティブなクエリが存在します。

4

2 に答える 2

1

250万レコードは、テーブルほど大きくはありません。私は2500万レコード以上のログテーブル(アクションの記録、サインイン、サインアウト、価格変更など)を持っています。

site_idおよび(日付部分のみ)でクエリを実行する場合はcreated、dateタイプのcreated_dateと次のようなインデックスを作成することをお勧めしINDEX (idx_lookup (site_id, created_date)ます。これにより、私が信じる最高のインデックスが得られるはずです。

于 2012-05-09T15:49:41.997 に答える
0

実行しているクエリの種類がわからない場合は、次のことを検討する必要があります。

  • サイトごとに個別のテーブルを作成します。それは素晴らしい解決策のようには思えないことは知っていますが、テーブルに別の高価なインデックスを作成する必要がなくなります。
  • レポートクエリを実行するための読み取り専用スレーブを設定します。これにより、メインデータベースへのストレスが軽減されます。
  • InnoDBは、すべての外部キーのインデックスも作成すると思います。これはテーブルのサイズには役立ちません(挿入も遅くなります)。定期的にページを削除しない限り、それらがなくても実行できます。

もっと考えられるなら、もっとヒントを追加します。

于 2012-05-09T15:04:56.693 に答える