2012-11-30 109 views
0

我有一个数据库表,UserRewards拥有三千万以上的行。在这一行中,每行都有一个用户ID和一个奖励ID(以及其他字段)。将多行转换为单列

有一个用户表(具有约400万独立用户),具有主键的用户ID等领域。 由于性能方面的原因,我希望将userrewards中每个用户的奖励ID移动到用户的连接字段中。 (新的nvarchar(4000)字段称为奖励) 我需要一个脚本,可以尽快做到这一点。

我用下面的脚本加入了奖励光标,但它只有大约每分钟100个用户,这将需要时间太长得到尽管约400万独立用户我处理。

set @rewards = (select REPLACE((SELECT rewardsId AS [data()] from userrewards 
where UsersID = @users_Id and BatchId = @batchId 
     FOR XML PATH('') ), ' ', ',')) 

任何建议,以优化?我即将尝试一段时间循环,看看它是如何工作的,但任何其他想法都会被大大接受。

编辑:

我的网站具有以下功能:

我们有大约400万用户谁已预先分配5-10“大奖”。这种关系在用户对话表中。

的用户来到现场,我们确定他们,查找在数据库中分配给他们的奖励。

的问题是,该网站是非常受欢迎的,所以我有大量的人访问该网站,同时请求他们的数据。以上将减少我的加入,但我知道这可能不是最好的解决方案。我的数据库服务器在我调整网站的10秒内达到100%的CPU使用率,所以大多数人的请求超时(它们显示为错误页面),或者他们得到结果,但不是在令人满意的时间。

有人能够提出一个更好的解决我的问题?

+0

...真的吗?我已经可以告诉你,在SQL中使用分隔列(多值列)是**真的**严重不满。 “对于性能”并不是一个令人信服的理由(查询该列往往比其值得的更麻烦) - 通常它们最终分列在分析数据库的不同列中。 4mil排马马虎虎,但花生在任何专用系统上。另外,游标/循环在SQL中通常是错误的(通常这可能是性能问题的最大部分)。你想要解决什么_actual_问题。还有哪些其他查询“很慢”? –

+0

查询速度很快,但我有5k-10k用户同时点击我的服务器,请求来自userrewards表的数据。 (拥有3000万行的那个)。这将加入到用户表和文件管理器上,并由用户提供唯一标识符。我在一列中更新的代码实现了更好的缓存,并且不会进行任何连接,速度也会提高很多。我只需要尽可能快地将我当前的大数据集转换为正确的格式。现在,SQL服务器是一个专用的盒子。我需要看到关于ugradding它..我应该RAM,CPU或两者?目前8GB的内存,2.00 zeon CPU – mp3duck

+0

就单列的东西而言,虽然它可能会皱眉,但我有效的代码比以前更快。 – mp3duck

回答

1

为什么我认为你尝试的方法是一个坏主意有几个原因。首先,你将如何维护用户表中的逗号分隔列表?有可能奖励是在晚上批量加载的,所以现在这不是一个真正的问题。即便如此,有一天你可能想要更频繁地分配奖励。

其次,当你想删除的奖励或更改其中一方的名字,会发生什么?您需要更新两个不同位置的信息,而不是更新一个表格。

如果您拥有400万用户,并有数千个并发访问,那么由于计时造成的小的不一致性将会很明显,并可能引发用户投诉。 CEO抱怨为什么抱怨增加可能不是你想要处理的事情。

另一种方法是在UserRewards上创建索引(UserId,BatchId,RewardsId)。据推测,每个字段只有几个字节,因此3000万条记录应该很容易适应8GB的内存(确保SQL Server几乎分配了所有的内存!)。您需要的查询可以通过此索引严格满足,而无需将UserRewards表带入内存。所以,只有索引需要被缓存。而且,它将针对此查询进行优化。

可能会减慢一切的一件事是分配奖励的频率。如果这些分配的读取速率达到读取速率的10%,则可能会有插入/更新阻塞读取。你想用READ_NOLOCK来完成查询,以避免这个问题。您还需要确保在记录或页面级别发生锁定,以避免与读取冲突。

+0

奖励按月分配,并且在月内不会更改。网站在奖励重新加载期间“关闭”。我已经在表格上有一个索引,但是我正在加入其他表格以获取实际数据。但是,我可以在Web服务器上缓存“奖励数据”,因为这一次在本月不会改变。作为索引,我应该包括主键在userrewads表上,或者只是外键(rewardsIDm usersID和batchID) – mp3duck

+0

我也使用uniqueidentifiers作为我的键..这是否会导致我的问题,也许呢?我想我会看看我能否获得另一个8GB内存的服务器 – mp3duck

0

也许为时已晚,但使用uniqueidentifiers作为关键字不仅会使您的存储空间翻两番(与使用ints作为关键字相比),还会使查询速度减慢数量级。避免!!!