1

现在建议的表结构是:-

data_table
->impressions
->clicks
->ctr

或者

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 展示次数 = 展示次数 + 1,ctr = 点击次数 / 展示次数 WHERE something = something

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

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

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

4

2 回答 2

1

首先,我假设表的索引很好,所以something = something谓词会很快导致相应的行,对吧?

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

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

于 2011-09-05T17:08:21.993 回答
0

也许这不是您问题的直接答案,但我认为值得注意的是。

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

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

For example, if you can afford to loose some impresions (remember that memcache does not persist data) you can do the impresions++ in memcache and update data in the DB every 5 minutes. It would decrease your load significantly.

I hope it helps you.

EDIT:

Storing CTR is a good idea, it's called "Denormalization", and may work in your application if it's a frequently required value.

于 2011-09-05T17:27:27.670 回答