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

Sql server 如何为聊天应用程序数据库选择索引,sql-server,database-design,indexing,chat,Sql Server,Database Design,Indexing,Chat,我使用数据库开发了一个小型聊天应用程序。我创建了如图所示的数据库。 我不熟悉索引,我想为查询选择合适的索引 我可以在Messages表中使用聚集索引吗?如果可以的话,哪一列(或几列)应该有聚集索引?还是应该使用非聚集索引 更新:我希望用户获取消息的查询是: Select TextContent From Messages where (SenderId='1' and ReciverID = '2') or (SenderId='2' and ReciverID = '1') order b

我使用数据库开发了一个小型聊天应用程序。我创建了如图所示的数据库。

我不熟悉索引,我想为查询选择合适的索引

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

更新:我希望用户获取消息的查询是:

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

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

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

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
如果您想从对话链中检索(比如)前10条最后的消息,重写一下查询可能会有所帮助:

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更有可能合并并连接会话的两个方向,而不是将它们单独排序

或者,使用
user1
user2
direction
,而不是发送方和接收方,以便
user1
(始终)和
direction
定义文本是从
user1
user2
,还是相反

这样,您就可以始终只对
user1=1和user2=2进行筛选,而不必担心
或联合

您可以在计算列中执行此操作,您还可以索引:

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)

您不为数据库创建索引,而是为查询创建索引。在我们看到查询之前,不可能通知索引。@谢谢您的评论。我更新了问题。回答得很好。但在中创建索引的方式不正确。索引的创建方式如下:在[dbo].[Message]([SenderId],[ReseverId],[MessageDate])上创建索引Index_Name最后一件事,我为什么要添加代理主键?@AhmedShamel:这样,例如,您就可以区分使用相同时间戳发布的消息。@AhmedShamel:在看到其他查询之前无法判断。但是,如果您要通过pk从其他表引用消息(比如用id链接消息url),这也会很方便。@AhmedShamel:主键和集群是不同的。您应该按最常查找的列进行聚类。
SELECT  *
FROM    messages
WHERE   user1 = 1
        AND user2 = 2 -- make sure lower number goes to user1, higher number goes to user2
ORDER BY
        date