如何为聊天应用程序数据库选择索引

时间:2015-06-30 22:22:03

标签: sql-server database-design indexing chat

我在数据库的小型聊天应用程序上工作。我创建了图像中显示的数据库。 Database for chat application

我是索引新手,我想为查询选择合适的索引。

我可以在Messages表中使用聚簇索引吗?如果可以的话,哪一列(或多列)应该有聚簇索引?或者我应该使用非聚集索引?

更新:我用来获取消息的查询是:

 Select TextContent From Messages where (SenderId='1' and ReciverID = '2') or (SenderId='2' and ReciverID = '1') order by date

SenderID和ReciverID的值只是为了澄清。

1 个答案:

答案 0 :(得分:2)

您可能应该在消息表中添加代理主键并创建索引:

ALTER TABLE messages ADD COLUMN id BIGINT NOT NULL IDENTITY

ALTER TABLE messages ADD CONSTRAINT pk_messages_id PRIMARY KEY (id)

CREATE INDEX ix_messages_sender_receiver_date (senderId, receiverId, date) ON messages

如果您想要从对话链中检索前十条最后一条消息,那么稍微重写一下您的查询可能会有所帮助:

SELECT  m.*
FROM    (
        SELECT  TOP 10
                *
        FROM    (
                SELECT  date, id
                FROM    messages
                WHERE   senderId = 1 AND receiverId = 2
                UNION
                SELECT  date, id
                FROM    messages
                WHERE   senderId = 2 AND receiverId = 1
                ) q
        ORDER BY
                date DESC, id DESC
        ) q
JOIN    messages m
ON      m.id = q.id

这样,SQL Server更有可能合并加入对话的两个方向,而不是单独排序。

或者,使用user1user2direction代替发件人和收件人,以便user1 < user2(始终)和direction定义文本从user1user2或反之亦然。

这样,您只需在user1 = 1 AND user2 = 2上进行过滤,而无需担心OR或工会。

您可以在计算列中执行此操作,您也可以将其编入索引:

ALTER TABLE messages ADD COLUMN user1 AS CASE WHEN senderId < receiverId THEN senderId ELSE receiverId END

ALTER TABLE messages ADD COLUMN user2 AS CASE WHEN senderId > receiverId THEN senderId ELSE receiverId END

ALTER TABLE messages ADD COLUMN direction AS CASE WHEN senderId < receiverId THEN 0 ELSE 1 END

CREATE INDEX ix_messages_user1_user2_date ON messages (user1, user2, date)

然后选择:

SELECT  *
FROM    messages
WHERE   user1 = 1
        AND user2 = 2 -- make sure lower number goes to user1, higher number goes to user2
ORDER BY
        date