50/50插入和选择。创建两个表或一个表

时间:2011-09-05 16:57:35

标签: mysql database optimization database-performance

现在提出的表结构是: -

data_table
->impressions
->clicks
->ctr

OR

data_table_1
->ctr

data_table_2
->impressions
->clicks

执行了哪些查询? 展示每秒大约有500次更新。每秒有大约1次点击更新。 ctr每秒大约有500次更新。

现在我的应用程序使用ctr对数据进行排序。 ctr是点击率,由ctr = clicks/impressions计算得出。现在我已经意识到除非有点击更新,否则ctr不需要更新,因为文章的所有印象都在增加,这会降低相同关系中的ctr,所以除非有点击,否则ctr不需要更新。

目前更新查询类似于“UPDATE data_table SET impressions = impressions + 1,ctr = clicks / impressions WHERE something = something

这意味着虽然一次更新了2个字段,但只执行了1个查询。

现在的瓶颈是这500次更新会导致此表上的选择速度变慢。每秒大约有20个选项。所以我想分开桌子。新表样式建议更新发生在单独的表上,选择发生在单独的表上。包含展示次数的数据表会经常更新,因此对其执行的展示的更新确实可以提高此表的性能。这意味着data_table_2上的选择也会更快,每次有人点击时都可以更新ctr。

所以,我只是想知道是否应该使用新的表结构。你有什么建议?我的建议的优点和缺点!

2 个答案:

答案 0 :(得分:1)

首先,我假设该表已被很好地编入索引,因此something = something谓词将很快产生相应的行,对吧?

进一步假设您的瓶颈是因为更新率高而导致磁盘吞吐量,那么根本不存储ctr值,因为它可以很容易地动态计算?由于您似乎受到更新的限制,因此只更新一个字段应该只是将数据写入磁盘的影响的一半。鉴于这种情况,CPU可能相对空闲,计算每个结果的点击次数/展示次数应该不是问题。您的方法会得到回报(再次假设磁盘是限制因素,假设它是可以通过查看CPU利用率轻松找到),那么您的方法将带来相当大的好处, iff 表或在两个不同的磁盘上。

如果CPU被证明是限制因素,那么可能是因为something = something谓词的评估非常复杂,在这种情况下,简化这一点应该是主要考虑因素,而不是拆分表。

答案 1 :(得分:0)

也许这不是你问题的直接答案,但我认为重要的是要注意。

我认为你应该考虑使用像Redis,MemcacheDB,MongDB,CouchDB这样的nosql数据库。 Relatational DBMS不适合这种用途。例如,每次更新任何列(UPDATE data_table SET impressions = impressions + 1)时,都会删除缓存,并且数据库必须命中磁盘。

其他人认为你可以考虑使用Memcache并在一段时间后将数据批量存储到磁盘上。

例如,如果你能够承受松散的一些压力(记住memcache不会持久存储数据),你可以在memcache中执行impresions ++并每5分钟更新一次数据库中的数据。它会显着降低你的负荷。

我希望它可以帮到你。

修改

存储点击率是一个好主意,它被称为“非规范化”,如果它是一个经常需要的值,它可以在你的应用程序中工作。