我有一张消息表
Key - UserId, MsgIndex
C1...Cn - some data columns
Cn+1 - Date, when message has been added to the table.
问题是与客户有关的最佳做法......
客户向服务器询问新消息......
有两种选择:
index > lastRxMsgIndex
的消息(客户端将保存最后收到的消息索引)date > lastRxMsgDate
的消息(客户端将保存最后一个rx消息日期 - 服务器将在获取消息结果时将其提供给他)哪个更好更快...
保持日期/ TS或索引是相同的,常识说要保持日期/ TS,但它对于msg索引是相同的。
MsgIndex位于表主键中,因此搜索日期(用户将有多条消息...)时速度会更快。
哪种方式最好?
由于 约阿夫
答案 0 :(得分:2)
首先关于性能:您可以在日期列中添加索引,以提高按日期搜索的性能。您很可能还希望在索引中包含user_id
。例如,您可以在(user_id, id)
或(user_id, date)
上使用组合索引,以便各个用户可以快速找到他们拥有的邮件,而服务器也不必扫描其他用户的邮件。
关于功能:将日期时间用作关键字的一个潜在问题是时间戳不通常是唯一的。如果您根据日期进行搜索,则可能(但不太可能)您将错过一条消息。以下是演示此问题的示例场景:
在16:01:04.312,该表包含两条消息:
id date message
1 2012-02-10 14:23:54 foo
2 2012-02-10 16:01:04 bar
客户端之前已收到第1行,现在请求并收到最新的行:
SELECT * FROM your_table WHERE date > '2012-02-10 14:23:54'
(1 row)
然后在16:01:04.420,一个新行以相同的时间戳进入数据库:
id date message
1 2012-02-10 14:23:54 foo
2 2012-02-10 16:01:04 bar
3 2012-02-10 16:01:04 baz
客户请求最新的行,但没有得到它:
SELECT * FROM your_table WHERE date > '2012-02-10 16:01:04'
(0 rows)
另一个问题是服务器的时间是否向后调整。这可能导致以后的消息插入更早的时间戳。如果您使用日期查找最新消息,也会错过这些消息。最好使用id
来避免这些潜在的问题。
答案 1 :(得分:2)
由于MsgIndex
是主键,因此它具有索引。因此,MsgIndex
的访问速度比使用日期比较快得多。
答案 2 :(得分:1)
如果您有大量收到的消息,您提到的前一种方式可以保证正常工作 后一种方式,如果你在同一天有两条消息(比如同一秒,因为我认为你不能更细粒度),你就搞砸了;)
我在使用每秒接收大量消息的系统之前使用了'go by index'方法。
答案 3 :(得分:1)
如果日期字段上有索引,则应该没有任何区别(假设您使用的是unix时间戳),因为您有两个整数按升序排列的字段,您希望所有的整数都大于X
timestamp列中可能存在非唯一值,但除非您使用聚合函数,否则这不会有问题,在这种情况下,您可以通过在所选字段中包含唯一主键来修复它。
鉴于这一事实,您只需要考虑:
就个人而言,我会选择timestamp字段,因为对于其他读取代码的人来说,你正在清楚地知道你在做什么,而使用id有点模糊,索引开销很小。