Mysql 但不一定是最佳方法)是以某种方式从该有序对的不同值导出: (LEAST(sender_id, recipient_id), GREATEST(recipient_id, sender_id))
然后Mysql 但不一定是最佳方法)是以某种方式从该有序对的不同值导出: (LEAST(sender_id, recipient_id), GREATEST(recipient_id, sender_id)),mysql,sql,django,django-models,database-design,Mysql,Sql,Django,Django Models,Database Design,然后索引(conversation\u id,id)可能是讨论的查询的关键。在这一点上,我们可以在讨论布尔值时再加上。我怀疑这最终将是最佳指标: INDEX(conversation_id, isRequest, id) (或者可能是前两列被替换了)。我有一个类似的情况,我认为最好在这里建立索引。你能解释一下吗?通过教科书和web&SO,特别是通过DBMS手册,学习查询引擎进行关系和SQL优化/实现的基本知识——所有这些都会立即产生索引、计划,统计与可搜索性。学习并应用这些基础知识后,请重新优
索引(conversation\u id,id)
可能是讨论的查询的关键。在这一点上,我们可以在讨论布尔值时再加上。我怀疑这最终将是最佳指标:
INDEX(conversation_id, isRequest, id)
(或者可能是前两列被替换了)。我有一个类似的情况,我认为最好在这里建立索引。你能解释一下吗?通过教科书和web&SO,特别是通过DBMS手册,学习查询引擎进行关系和SQL优化/实现的基本知识——所有这些都会立即产生索引、计划,统计与可搜索性。学习并应用这些基础知识后,请重新优化。需要对问题进行适当的研究。请参阅其他链接和文本上方的投票箭头鼠标。请用文字描述您的示例试图做什么。也许它在寻找它们之间的信息?但是
LEFT JOIN
在做什么?@Rage-isRequest如何符合您的示例?我有一个类似的情况,我认为最好在这里建立索引。你能解释一下你自己吗?通过教科书、web和SO,特别是DBMS手册,学习查询引擎的关系和SQL优化/实现的基本知识,所有这些都会立即导致索引、计划、统计和可搜索性。学习并应用这些基础知识后,请重新优化。需要对问题进行适当的研究。请参阅其他链接和文本上方的投票箭头鼠标。请用文字描述您的示例试图做什么。也许它在寻找它们之间的信息?但是LEFT JOIN
在做什么?@Rage-isRequest如何适合您的示例?不幸的是,我的查询比WHERE子句稍微复杂一些。上面的示例查询用于显示用户最近的对话。它返回他最近20次谈话中发送的最后一条消息。更新后的^2个嵌套表扫描非常“不好”。是否有任何方法可以在提高性能的情况下实现相同的查询?我需要从用户最近的20次对话中获取最后一条消息。如果我的背景不清楚,请告诉我。我希望我有Instagram的直接消息的源代码。@Rage-myapp_message和app_message
之间的区别是什么?拼写错误,只是修复了一下。我想你可能了解了一些东西,但查询没有在MySQL中编译。不幸的是,我的查询比WHERE子句稍微复杂一些。上面的示例查询用于显示用户最近的对话。它返回他最近20次谈话中发送的最后一条消息。更新后的^2个嵌套表扫描非常“不好”。是否有任何方法可以在提高性能的情况下实现相同的查询?我需要从用户最近的20次对话中获取最后一条消息。如果我的背景不清楚,请告诉我。我希望我有Instagram的直接消息的源代码。@Rage-myapp_消息和app_消息之间的区别是什么,我想你可能知道了一些事情,但是查询没有在MySQL中编译。你是对的,我当然有其他用于查询的筛选器,但它们是索引的外键筛选器,但是你是对的,它们没有在这个表中一起索引。我在上面提供了一个示例查询。筛选器:发件人id(FK)、收件人id(FK)、isRequest。也许我应该把这三个都索引在一起?你是对的,我当然有其他的查询过滤器,但是它们是外键过滤器,它们被索引了,但是你是对的,它们在这个表中没有一起索引。我在上面提供了一个示例查询。筛选器:发件人id(FK)、收件人id(FK)、isRequest。也许我应该把这三个索引在一起?你肯定知道一些事情。在我看来,查询特定对话时,“对话id”列将非常有用。但是,在我的应用程序上下文中,我没有会话ID,而是搜索20条最新消息(每条消息来自一个唯一的会话)。也许这将包括一个新的表CONVERSATION,它存储每个用户的对话。列:conversation\u id、user\u A、user\u B。前面提到的查询将首先获取用户参与的所有conversation\u id,然后从message表中查询max message\u id?这个解决方案的一个扩展可能是拥有一个如前所述的对话表,以及拥有一个lastMessage\u id,它是message表中message\u id的外键。每次现有对话中有人发送消息时,它不仅会将此消息添加到消息表中,还会更新对话的lastMessage_id外键,以便对话现在指向最新的消息。现在的问题是:获取该用户id涉及的所有对话。我们还有一个指向最后一条消息的指针。这种策略的最佳索引是什么?我会将conversation\u id
添加到当前表中。它将由一些笨拙的查询(如我们正在处理的查询)初始化,然后一个相当简单的查询将使它继续运行。另一个表是conversation\u id
(auto\u inc PK),加上2个用户。但最终还是会有两个连接和一个联合(或其他什么),以使查询更快。是的,指向最后一条消息\u id
的链接可能会起作用。但是回到布尔值——仔细想想它对更新最后一条消息\u id
的影响。你肯定知道了一些事情。在我看来,查询特定对话时,“对话id”列将非常有用。但是,在我的应用程序上下文中,我没有会话ID,而是搜索20条最新消息(每条消息来自一个唯一的会话)。也许这会包括
SELECT T4.userB_id, T4.username, T4.profilePic, T4.conver_id,
T4.message
(
SELECT T1.userB_id, T2.username, T2.profilePic, T1.conversation_id,
T1.lastMessage_id
FROM
(
SELECT userB_id, conversation_id, lastMessage_id
FROM rage.userconversation
WHERE userA_id = {userID}
AND isRequest=False
) AS T1
LEFT JOIN rage.user AS T2 ON T1.userB_id = T2.id AS T3
)
LEFT JOIN rage.message AS T4 ON T1.lastMessage_id = T4.id
ORDER BY T4.id DESC
LIMIT 20
RESULT (for userID = 1)
---------------------------------------------------------------
userB_id username profilePic message conver_id
8 John 8.jpg "hey man" 3
2 Daisy 2.jpg "great! hbu" 4
SELECT * FROM rage.message WHERE conversation_id={conver_id} ORDER BY id DESC LIMIT 20
WHERE IsRequest = True
AND UserId = 12345
INDEX(IsRequest, UserId)
( SELECT m1.id, m1.sender_id, m1.recipient_id, m1.message ...
FROM myapp_message AS m1
LEFT JOIN app_message AS m2
ON m1.sender_id = m2.sender_id
AND m1.id < m2.id
WHERE m2.id IS NULL
AND m1.sender_id = {userID}
AND m1.isRequest = False
order by id desc
LIMIT 20
) UNION ALL (
SELECT m1.id, m1.sender_id, m1.recipient_id, m1.message ...
FROM myapp_message AS m1
LEFT JOIN app_message AS m2
ON m1.recipient_id = m2.recipient_id
AND m1.id < m2.id
WHERE m2.id IS NULL
AND m1.recipient_id= {userID}
AND m1.isRequest = False
order by id desc
LIMIT 20
) ORDER BY id DESC LIMIT 20
SELECT m...
FROM
( SELECT xid, MAX(mid) AS mid
FROM
(
( SELECT recipient_id AS xid,
MAX(mid) AS mid -- The last message TO each recipient
FROM WHERE sender_id = 1234 -- FROM the user in question
GROUP BY recipient_id
ORDER BY 2 DESC -- ("2nd column")
LIMIT 20
)
UNION ALL
( SELECT sender_id AS xid,
MAX(mid) AS mid -- The last message FROM each sender
FROM WHERE recipient_id = 1234 -- TO the user
GROUP BY sender_id
ORDER BY 2 DESC
LIMIT 20
)
) AS y
GROUP BY xid -- yes, repeated
ORDER BY mid DESC -- yes, repeated
LIMIT 20 -- yes, repeated
) AS x
JOIN messages AS m ON m.mid = x.mid
INDEX(sender_id, recipient_id, mid)
INDEX(recipient_id, sender_id, mid)
(LEAST(sender_id, recipient_id), GREATEST(recipient_id, sender_id))
INDEX(conversation_id, isRequest, id)