2016-05-06 5 views
0

私は基本的に同じコードの2つのバージョンを得ました。 (下記参照)バージョン1は2秒で実行され、バージョン2は0.5〜0.6秒で実行されます。私がどこから選んでいるのかは現在1000万行ありますが、この数字はかなり速くなります。私は可能であればさらに下に行きたいです。問題は、私はバージョン2を使用し、私はその30倍(異なるステータス、異なるユーザ名など)を呼び出す必要があること、最終的な数はまだ私が必要なもののためには大きすぎることになるだろうさ。代わりに私が使用できる第3版はありますか?それとも、私がこれをもっと速くすることができる他の方法がありますか?それとも、私ができる唯一のことはインデックスで遊ぶことです。カウントパフォーマンスの最適化

基本的にすべてのこれらのカウントは、Webアプリケーションで最も訪問された画面に表示されるだろう、と1000人のユーザが同じ時間にシステムを使用しているとき、30 * 0.5秒は少しすぎに聞こえます。

バージョン1

declare @a1 datetime; set @a1 = GETDATE() 

declare @int1 INT,@int2 INT,@int3 INT,@int4 INT,@int5 INT,@int6 INT,@int7 INT,@int8 INT 

select @int1 = COUNT(Id) from ToDos where StatusId = 1 and stringUserId = 'a' 
select @int2 = COUNT(Id) from ToDos where StatusId = 1 and stringUserId = 'b' 
select @int3 = COUNT(Id) from ToDos where StatusId = 1 and stringUserId = 'c' 
select @int4 = COUNT(Id) from ToDos where StatusId = 1 and stringUserId = 'd' 
select @int5 = COUNT(Id) from ToDos where StatusId = 1 and stringUserId = 'e' 
select @int6 = COUNT(Id) from ToDos where StatusId = 1 and stringUserId = 'f' 
select @int7 = COUNT(Id) from ToDos where StatusId = 1 and stringUserId = 'g' 
select @int8 = COUNT(Id) from ToDos where StatusId = 1 and stringUserId = 'h' 

select @int1, @int2, @int3, @int4, @int5, @int6, @int7, @int8 

SELECT DATEDIFF(MILLISECOND, @a1, GETDATE()) 

バージョン2

declare @a1 datetime; set @a1 = GETDATE() 

select stringUserId, count(stringUserId) 
from ToDos 
where StatusId = 1 and stringUserId in ('a','b','c','d','e','f','g','h') 
group by stringUserId 
order by COUNT(stringUserId) desc 

SELECT DATEDIFF(MILLISECOND, @a1, GETDATE()) 
+0

によって順序なぜあなたは番目のバージョンを30回コールする必要がありますか?あなたは必要なすべての情報を選択するために1つのクエリしか必要としません。 'StatusId'フィルタを削除するだけです。それを 'Group By'に追加してください。結果には、必要と思われるすべてのステータスカウントが含まれています。 –

+0

パフォーマンスの問題が '含まANALYZE'となどテーブルサイズ、インデックス、現在の時のパフォーマンス、欲求時間に関するいくつかの情報を説明しなければならない' Slow'は相対的な用語であり、我々は比較することで、実際の値を必要としています。 [** MySQL **](http://dba.stackexchange.com/questions/15371/how-do-i-get-the-execution-plan-for-a-view) [クエリアナライザ](https://technet.microsoft.com/en-us/library/aa216945(v = sql.80).aspx) –

+0

@JuanCarlosOropeza:これはsql-serverではなくmysqlです。しかし、あなたは右とにかく –

答えて

1

は、条件付きの数を試してみてください。

select 
    @int1 = COUNT(CASE WHEN stringUserId = 'a' THEN 1 END), 
    @int2 = COUNT(CASE WHEN stringUserId = 'b' THEN 1 END), 
    @int3 = COUNT(CASE WHEN stringUserId = 'c' THEN 1 END), 
    @int4 = COUNT(CASE WHEN stringUserId = 'd' THEN 1 END), 
    @int5 = COUNT(CASE WHEN stringUserId = 'e' THEN 1 END), 
    @int6 = COUNT(CASE WHEN stringUserId = 'f' THEN 1 END), 
    @int7 = COUNT(CASE WHEN stringUserId = 'g' THEN 1 END), 
    @int8 = COUNT(CASE WHEN stringUserId = 'h' THEN 1 END) 
from ToDos 
where StatusId = 1 

はFYI:デフォルトのためNULLCOUNT doesntのカウントヌル

+0

この質問の更新情報クエリプランを確認できましたか? –

0

を返しますので、私はあなたが試みることができるCASEためELSE一部を含むdidntは:からカウント機能を解消

select a.* from (select stringUserId, count(stringUserId) as IDCount 
from ToDos 
where StatusId = 1 and stringUserId in ('a','b','c','d','e','f','g','h') 
group by stringUserId) a 
order by a.IDCount desc 

+0

あなたは違いを生むのですか? 'order by 'はすでに' group by'の後にあるからです。 –

+0

order byはカウントも計算する必要があります。カウントは2回起こっています。私はこのテクニックが過去のいくつかの改善をしたことを発見しましたが、OPデータにアクセスできない場合、このケースで役立つかどうかわかりません。書かれたクエリの中にあるものは、データベースエンジンが何をするかを決定する可能性のある順序と関係がありません。 – HLGEM