2012-02-14 3 views
1

私は SQLクエリを最適化する方法は?別のものは非常に遅いですね?

はどのように最適化すること)=デシベルのspeccialist、それほど問題ではない午前:

select count(DISTINCT userid) 
from users 
where date_trunc('month',login_date)=date_trunc('month','2012-01-12'::date) 

表の行が少ないし、150万である数えます。私はlogin_dateにインデックスを持っていますが、クエリの実行時間はそれがないと同じです。フィールドuseridも主キーです。

サーバーマシンでは、このクエリには2000ミリ秒以上かかります。最高のパフォーマンスを引き出すのを助けることができる最初の男は、評判を得るでしょう++:D

---------------- a'b'c'd'e'f'g ' h '解決策----------------------------------

CREATE OR REPLACE FUNCTION my_date_trunc_month(some_date DATE) 
    RETURNS DATE 
AS $$ 
BEGIN 
    return date_trunc('month',$1); 
END; 
$$LANGUAGE plpgsql 
IMMUTABLE; 


CREATE INDEX computedIdx ON gameuser_daily_activity (my_date_trunc_month(login_date)); 

select count(DISTINCT gameuser_fk) from gameuser_daily_activity where my_date_trunc_month(login_date)=my_date_trunc_month('2012-01-12'::date) 

そして110 ms: )

答えて

4

このインデックスを定義します。

CREATE INDEX computedIdx ON users (date_trunc('month',login_date))

+0

Hm、ERROR:インデックス式の関数は、IMMUTABLEとマークする必要があります。 – whatswrong

+0

http://stackoverflow.com/questions/5973030/error-functions-in-index-expression-must-be-marked-immutable - マークを付けた関数を作成します。日付を変換するために不変です。 –

+0

ありがとうございます。 110ミリ秒に最適化!カスタム関数のないソリューションが存在するのを待つかどうか=) – whatswrong

3

ユーザーIDが主キーである場合、あなたがディを配置する必要がいけない明瞭になりますその中stinct ...主キー

+0

申し訳ありませんがPKは両方のフィールド(userid、login_date)にあります。 – whatswrong

+0

。 date_trunc( 'month'、login_date)= '01' はパフォーマンスを少し向上させる可能性があり、UserIDはプライマリキーであったはずです。他の多くのケースでも役に立ちます。 –

+0

実際にはテーブル名はuser_daily_activityです。私はそれをユーザーに改名しましたが、私はそれをすべきではありません。複合キーが必要です – whatswrong

1

にインデックスを付け、クラスタ化 http://www.w3schools.com/sql/sql_primarykey.asp

と兼ね備えあなたはこのような何かを試すことができますか?

select count(DISTINCT userid) 
from users 
where 
login_date >= '2012-01-12'::date and 
login_date < '2012-01-12'::date + '1month'::interval 

インデックスされた列の前後の式を削除すると、オプティマイザの仕事が簡単になります。

+0

もちろん、これを有効にするにはlogin_dateにインデックスが必要です。 – gpeche

+0

Hm、それは140ミリ秒で高速動作します。しかし、結果のデータは異なります=) – whatswrong

+0

私はPostgreSQLのエキスパートではありません。あなたは日付範囲で作業する必要があります。つまり、索引付けされた列の周りに式を置かないようにして、オプティマイザはその索引を使用するという明確なヒントを得ます。 – gpeche