1

非常に大量の状況に近づいたのはこれが初めてです。これは MySQL ベースの広告サーバーです。ただし、使用されるクエリには多くの JOIN が組み込まれており、通常はただ遅いだけです。(これは Rails ActiveRecord です)

sel = Ads.find(:all, :select => '*', :joins => "ads.campaign_id = キャンペーン.id でキャンペーンに参加 キャンペーン.user_id = users.id でユーザーに参加 LEFT JOIN 国で国に参加.campaign_id = Campaign.id LEFT JOIN キーワード ON キーワード.campaign_id = キャンペーン.id", :conditions => [flashstr + "keywords.word = ? AND ads.format = ? AND キャンペーン.cenabled = 1 AND (countries.country IS NULL OR countries .country = ?) AND ads.enabled = 1 AND Campaigns.dailyenabled = 1 AND users.uenabled = 1", kw, format, viewer['country'][0]], :order => order, :limit =>限)

私の質問:

  1. JOIN をサポートしているが、はるかに高速な MySQL のような代替データベースはありますか? (Postgre があることは知っていますが、まだ評価中です。)

  2. それ以外の場合、MySQL インスタンスを起動し、ローカル データベースをメモリにロードし、5 分ごとに再ロードすることは役に立ちますか?

  3. それ以外の場合、この操作全体を Redis または Cassandra に切り替えて、何らかの方法で JOIN 動作を変更して、NoSQL の (JOIN できない) 性質に一致させる方法はありますか?

ありがとうございました!


編集:ここに詳細があります:

フラット化された選択で完全に実行された SQL (上で切り捨てられています):

SELECT キャンペーン.id、キャンペーン.guid、キャンペーン.user_id、キャンペーン.dailylimit、キャンペーン.インプレッション、キャンペーン.cenabled、キャンペーン.dayspent、キャンペーン.dailyenabled、キャンペーン.fr、ads.id、ads.guid、ads.user_id、ads .campaign_id、ads.format、ads.enabled、ads.datafile、ads.data1、ads.data2、ads.originalfilename、ads.aid、ads.impressions、countries.id、countries.guid、countries.campaign_id、countrys.country 、keywords.id、keywords.campaign_id、keywords.word、keywords.bid FROMadsads.campaign_id = キャンペーン.id でキャンペーンを結合 キャンペーンでユーザーを結合.user_id = users.id 国で左結合 国.キャンペーン_id = キャンペーン.id 左結合 キーワードでキーワードを結合' AND ads.format = 10 AND Campaign.cenabled = 1 AND (countries.country IS NULL OR countries.country = 82) AND ads.enabled = 1 AND Campaigns.dailyenabled = 1 AND users.uenabled = 1 AND ads.datafile ! = '') ORDER BY キーワード.bid DESC LIMIT 1,1

EXPLAIN/実行計画:

+----+-------------+-----------+--------+------------------+-------------+---------+------------------------------------+------+----------------------------------------------+
| id | select_type | table     | type   | possible_keys    | key         | key_len | ref                                | rows | Extra                                        |
+----+-------------+-----------+--------+------------------+-------------+---------+------------------------------------+------+----------------------------------------------+
|  1 | SIMPLE      | keywords  | ref    | campaign_id,word | word        | 257     | const                              |    9 | Using where; Using temporary; Using filesort | 
|  1 | SIMPLE      | ads       | ref    | campaign_id      | campaign_id | 4       | e_development.keywords.campaign_id |    8 | Using where                                  | 
|  1 | SIMPLE      | campaigns | eq_ref | PRIMARY          | PRIMARY     | 4       | e_development.keywords.campaign_id |    1 | Using where                                  | 
|  1 | SIMPLE      | users     | eq_ref | PRIMARY          | PRIMARY     | 4       | e_development.campaigns.user_id    |    1 | Using where                                  | 
|  1 | SIMPLE      | countries | ALL    | campaign_id      | NULL        | NULL    | NULL                               |    4 | Using where                                  | 
+----+-------------+-----------+--------+------------------+-------------+---------+------------------------------------+------+----------------------------------------------+

(これは開発データベース上にあり、本番バージョンほど多くの行はありません。)

定義された指標:

ads -> id (primary, autoinc) + aid (unique) + campaign_id (index) + user_id (index)
campaigns -> id (primary, autoinc) + user_id (index)
countries -> id (primary, autoinc) + campaign_id (index) + country (index) + user_id (index)
keywords -> id (primary, autoinc) + campaign_id (index) + word (index) + user_id (index)
user -> id (primary, autoinc)
4

2 に答える 2

3

データベース理論とノミナルプラクティスは、ほとんどの場合にフレームワークを提供するために存在します。すべてのデータベース使用パターンが第 3 正規形にうまく収まるわけではありません。したがって、NoSQLの出現。これらのデータベースは、ほとんどの場合うまく機能しませんが、特定のケースではうまく機能します。それらがうまく機能する理由の 1 つは、通常の RDBMS のようには機能しないためです。Cassandra には「参加」するための機能がいくつかありますが、正確な詳細は覚えていません。簡単に理解したい場合は、Digg 開発者ブログをお勧めします。簡単な説明があります。

問題は、4 つのテーブルの結合が mySQL よりも遅いということです。確実に知る唯一の方法は、新しい DBMS を学習し、それをインストールし、インストールを調整することです。また、MySQL を調整し、すべてのデータをセットアップすることもできます。 .

まったく同じ問題を別のエンジンでまったく同じ方法で解決しようとしてもうまくいきません... NoSQL を使用する RDBMS 開発者ではなく、NoSQL 開発者のように考える必要があります。

しかし、欲求不満が示唆するように、問題について考えることができます。

第 3 正規形があるのはなぜですか? 主に更新のしやすさ。数十行ではなく 1 行を更新します。また、データを制限するのにも役立ちます。国テーブルへの国を慎重に追加すると、キャンペーン テーブルに悪い国が表示されることはありません。その後、3NF はクエリを高速化しないため、レポート データベース、OLAP、キューブ、スター スキーマを発明しました。

重要なのは、レポートと編集/キャプチャの構造が異なることです。

欲求不満が言ったように、基礎となるデータの変化の速度を決定します。本当に 5 分ごとに国を追加しているとしたら、私は唖然とします。キャンペーン?おそらくたまに?広告?1日に数回。完全にフラット化されたテーブルを作成してインデックスを作成するには、どのくらいの時間がかかりますか? それは何行になりますか?そのサイクル時間が更新頻度よりもはるかに短い場合...それを構築して確認してください。クエリ速度をテストします。これは、まったく新しい DB を使用するよりも安価な実験です。

于 2010-06-14T22:07:34.240 に答える
1

実行計画を分析しましたか? インデックスを分析しましたか?

私の最初の推測では、 forのインデックス、 campaignsforのuser_idインデックス、onのインデックスが必要だということです。クエリの実行内容を確認するには、実行計画を取得する必要があります。countriescampaign_idkeywordscampaign_id

もう 1 つのオプション: この結果セットのデータはどのくらいの頻度で変更されますか? 分単位で?時間?日?毎日または毎時 (数時間) の場合は、この結果セットのすべての列 (または頻繁に変更される可能性が低い列のみ) を含み、このクエリによって入力されるセカンダリ テーブルを用意することをお勧めします。n時間ごと。次に、アプリはセカンダリ テーブルにクエリを実行する (または、頻繁にデータが変更される 1 つのテーブルに結合する) だけで、その方が高速になる可能性があります。

于 2010-06-14T20:15:39.420 に答える