2012-01-20 20 views
0

私は150,000以上の行(成長)以上の数値を計算する必要がありますが、私のクエリはかなり遅いです。ここで私のクエリを改善するには?

CREATE TABLEです:

CREATE TABLE `device` (
    `id` int(11) NOT NULL auto_increment, 
    `registration_id` varchar(255) NOT NULL, 
    `creation_date` datetime NOT NULL, 
    `latest_activity_date` datetime NOT NULL, 
    `status` varchar(255) NOT NULL, 
    `type` varchar(255) NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `IDX_8484BF65454ADE21` (`latest_activity_date`,`status`,`type`) 
) ENGINE=InnoDB AUTO_INCREMENT=160969 DEFAULT CHARSET=utf8; 


CREATE TABLE `article` (
    `id` int(11) NOT NULL auto_increment, 
    `summary` longtext NOT NULL, 
    `creation_date` datetime NOT NULL, 
    `published_date` datetime default NULL, 
    `updated_date` datetime default NULL, 
    PRIMARY KEY (`id`), 
    KEY `IDX_A5051EECA76ED395` (`user_id`), 
    KEY `IDX_A5051EEC7B00651C9E0806AB` (`published_date`) 
) ENGINE=InnoDB AUTO_INCREMENT=20216 DEFAULT CHARSET=utf8; 

私は彼らの最新の活動日の与えられた各デバイスの公表条の数を取得する必要があります。

だから私は実行します。

SELECT m.registration_id, COUNT(a.id) 
FROM device m, article a 
WHERE (
    m.latest_activity_date < CURRENT_TIMESTAMP AND 
    a.published_date >= m.latest_activity_date AND 
    m.status = 'enabled' AND 
    a.published_date <= CURRENT_TIMESTAMP AND (
     m.registration_id <> '' OR 
     m.registration_id IS NOT NULL 
    ) 
) AND m.type = 'foo' 
GROUP BY m.registration_id 
HAVING COUNT(a.id) > 0 

しかし、このクエリは少し遅いですが

(約〜3000件の記事&〜150000のデバイスのための50秒かけて)私はEXPLAINしようとしたが、それはいずれかを与えるものではありません手がかり私はまた、任意のアイデアINNER JOINLEFT JOIN ON a.published_date >= m.latest_activity_dateが、同じ結果の両方を使用して(参加。また、(しかし、それは「可能インデックス」としてIDX_8484BF65454ADE21を示して)すべての行が何のインデックスが使用されていない読まれていることを示している。

明示を試してみましたか?無に加えて

+0

デバイステーブルと記事テーブルの間に相関列(JOIN)が表示されません... – DRapp

+0

ええ、私はここに「暗黙の結合」を投稿しましたが、明示的な結合も試みました。同じ結果。 – Trent

+0

私の現在の答えを膨らませないように...それはいくつかの "最後の活動"イベントを引き起こし続ける単一のデバイスですか?複数のデバイスがあり、それぞれに独自のアクティビティイベントが発生します。もしそうなら、どれくらいの距離をあなたがどんなデバイスの活動を許可したいのかがより良いかもしれません。 1月18日、Device BとDevice Aに関連したArticle Xをどうやって相互に関連付けるのでしょうか?各テーブルからいくつかのデータサンプルを投稿し、どのように相関させるべきか、あなたが期待するものを表示できますか?約10個のデバイスと20個の記事要素のダンプを行います。 – DRapp

答えて

0

は、テーブル間の結合条件、それは基本的にデカルト(何混乱)それらに対して参加くださいます。

加えて、私は「固定」のあなたの基準に最高基づいてインデックスを調整します最初に値を入力してから、日付の範囲を指定して...明示する...

上の10

指数(ステータス、タイプ、日付...)

最後に、なぜフィールドのこれらのタイプは、より多くても、通常の条件下では省略し、されるだろう...ステータスとタイプのためにあまりにも長い間、フィールド、私は15-20文字のような列を持っています。 1フィールドあたり最大255文字のインデックスページを持つことで、クエリの時間も大幅に短縮されます。

+0

ステータス/タイプと可能な値の数が少ないすべてのフィールドについては、 'ENUM'型を使用する方が良いでしょう。その場合、mysqlはデータを数値として格納します(インデックスは小さく、速くなります)。データは文字列として取得されます。 – Marki555

+0

@ Marki555、私は同意しますが、あまりにも多くを混乱させたくありませんでした。 – DRapp

+0

こんにちは、あなたの答えをありがとう、(ステータス、タイプ、日付)のインデックスを示唆し、それは実際に私がしたものです:KEY 'IDX_8484BF65454ADE21'(' latest_activity_date'、 'status'、' type')。私はその乱雑なデカルト製品について知っていますが、それを避ける方法はありません。 なぜ私のクエリは、デバイステーブルのすべての行を読み込み、タイプとステータスで一部を除外しているのですか? – Trent

関連する問題