[MSSQL]SQLにおけるGroupパケット取得Top N方法は、優先的なrow_を実現する。number

5311 ワード

製品リストがあります。id、name、city、addtimeの四つのフィールドが含まれています。レポートは都市ごとにグループ化される必要があるので、各都市の最新の10の製品を統計して、この表に100万のデータを挿入して、次のシリーズのテストを行いました。コードは以下の通りです。
CREATE TABLE [dbo].[products]( 
[id] [int] IDENTITY(1,1) NOT NULL, 
[name] [nvarchar](50) NULL, 
[addtime] [datetime] NULL, 
[city] [nvarchar](10) NULL, 
CONSTRAINT [PK_products] PRIMARY KEY CLUSTERED 
( 
[id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
1、row_を採用するnumberメソッドは、5回実行して、平均して8秒ぐらいで、最も速いです。コードは以下の通りです。
 select no, id,name,city from (select no =row_number() over (partition by city order by addtime desc), * from products)t where no< 11 order by city asc,addtime desc 
2、cross apply方法を採用して、3回実行しました。ほとんど3分5秒以上で、もう遅いです。コードは以下の通りです。
select distinct b.id,b.name,b.city from products a cross apply (select top 10 * from products where city = a.city order by addtime desc) b 
3、Countクエリを採用して、2回だけ実行しました。初めて5分まで実行した場合、タスクの実行をキャンセルしました。二回目は13分まで行われましたが、Holdが住まずに停止しました。本当に耐えられません。コードは以下の通りです。
select id,name,city from products a where ( select count(city) from products where a.city = city and addtime>a.addtime) < 10 order by city asc,addtime desc
4、ラベルの方法を採用して、この最後のテストは5回実行しました。毎回10秒で完成します。いい感じです。コードは以下の通りです。
  declare @city nvarchar(10) 
create table #Top(id int,name nvarchar(50),city nvarchar(10),addtime datetime) declare mycursor cursor for select distinct city from products order by city asc open mycursor fetch next from mycursor into @city while @@fetch_status =0 begin insert into #Top select top 10 id,name,city,addtime from products where city = @city fetch next from mycursor into @city end close mycursor deallocate mycursor Select * from #Top order by city asc,addtime desc drop table #Top
上記の比較では、Groupに対してTop Nシーンを取得する場合、優先的にrow_を選択することができます。number、ラベルcursorの次に、他の二つは基本的に考慮しなくて、データ量が大きい時はぜんぜん使えません。