如何为聊天应用数据库选择索引
How to choose indexes for chat application database
我在开发一个带有数据库的小型聊天应用程序。我创建了图中所示的数据库。
我是索引新手,我想为查询选择合适的索引。
我可以在消息中使用聚簇索引吗table?如果可以的话,哪一列(或多列)应该有聚簇索引?还是应该使用非聚集索引?
更新:我用户获取消息的查询是:
Select TextContent From Messages where (SenderId='1' and ReciverID = '2') or (SenderId='2' and ReciverID = '1') order by date
SenderID 和 ReciverID 的值只是为了说明。
您可能应该为您的消息添加一个代理主键 table 并创建一个索引:
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 服务器更有可能合并加入对话的两个方向,而不是分别对它们进行排序。
或者,使用 user1
、user2
和 direction
,而不是发送方和接收方,以便 user1 < user2
(始终)和 direction
定义是否文本从 user1
变为 user2
,反之亦然。
这样,您始终可以简单地过滤 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:
SELECT *
FROM messages
WHERE user1 = 1
AND user2 = 2 -- make sure lower number goes to user1, higher number goes to user2
ORDER BY
date
我在开发一个带有数据库的小型聊天应用程序。我创建了图中所示的数据库。
我是索引新手,我想为查询选择合适的索引。
我可以在消息中使用聚簇索引吗table?如果可以的话,哪一列(或多列)应该有聚簇索引?还是应该使用非聚集索引?
更新:我用户获取消息的查询是:
Select TextContent From Messages where (SenderId='1' and ReciverID = '2') or (SenderId='2' and ReciverID = '1') order by date
SenderID 和 ReciverID 的值只是为了说明。
您可能应该为您的消息添加一个代理主键 table 并创建一个索引:
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 服务器更有可能合并加入对话的两个方向,而不是分别对它们进行排序。
或者,使用 user1
、user2
和 direction
,而不是发送方和接收方,以便 user1 < user2
(始终)和 direction
定义是否文本从 user1
变为 user2
,反之亦然。
这样,您始终可以简单地过滤 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:
SELECT *
FROM messages
WHERE user1 = 1
AND user2 = 2 -- make sure lower number goes to user1, higher number goes to user2
ORDER BY
date