Mysql 表中有成对的朋友,如何创建一个视图来抽象用户的朋友列表?

Mysql 表中有成对的朋友,如何创建一个视图来抽象用户的朋友列表?,mysql,view,indexing,query-optimization,Mysql,View,Indexing,Query Optimization,我有一张who的朋友和who的表格,它有以下简单的内容: 用户号1 |用户号2 | 具有非唯一索引:索引\u在\u用户1上和索引\u在\u用户2上 两列都包含相同类型的数据,友谊总是双向的 1 | 2 =用户1是用户2的朋友,用户2是用户1的朋友 我想要的是得到一个查询,该查询将始终为我提供任何用户id的朋友列表 到目前为止,我一直在使用 SELECT if(`user_id1` = $user_id, `user_id2`, `user_id1`) as friend FROM `Friend

我有一张who的朋友和who的表格,它有以下简单的内容:

用户号1 |用户号2 |

具有非唯一索引:索引\u在\u用户1上和索引\u在\u用户2上

两列都包含相同类型的数据,友谊总是双向的

1 | 2

=用户1是用户2的朋友,用户2是用户1的朋友

我想要的是得到一个查询,该查询将始终为我提供任何用户id的朋友列表

到目前为止,我一直在使用

SELECT if(`user_id1` = $user_id, `user_id2`, `user_id1`) as friend
FROM `Friends`
WHERE `user_id1` = $user_id OR `user_id2` = $user_id
但是我有更多的查询,我想把这些信息作为一个子查询,并把包含这个查询的视图作为一个子查询。所以我在寻找一种方法来抽象这个,有一些简单的选择,总是可以得到我朋友的id,而不会有那个if语句的麻烦

我对union有一个想法:

CREATE OR REPLACE VIEW get_friend AS 
SELECT 
    `user_id1` as subject,
    `user_id2` as friend,
    FROM `Friends` 
    USE INDEX (`index_on_user1`)
UNION
SELECT
    `user_id2` as subject,
    `user_id1` as friend,
    FROM `Friends` 
    USE INDEX (`index_on_user2`)
使用简单的SELECT-friend-FROM-get\u-friend,其中subject=$user\u-id来获得结果,它可以工作

但请解释选择。。。表示它不使用索引,即使有提示也不使用


我如何让它使用这些索引?有可能吗?还有其他解决方案吗?

为了使用索引,需要在UNION语句中的各个查询中使用WHERE子句。基本上,您对视图的查询就是这样做的

SELECT subject, friend FROM
(SELECT 
    `user_id1` as subject,
    `user_id2` as friend,
    FROM `Friends` 
    USE INDEX (`index_on_user1`)
UNION
SELECT
    `user_id2` as subject,
    `user_id1` as friend,
    FROM `Friends` 
    USE INDEX (`index_on_user2`)
) WHERE friend = <some number>

尝试在填写了适当的where子句的情况下对UNION运行EXPLAIN查询,您应该会看到索引正在被使用

不能在一个视图上使用不同的索引。为了获得所需的性能,您必须像您的union一样在需要的地方编写原始SQL

更好的解决方案是存储关系的两个方向。这是一些非规范化的数据,但不是很多。这样做将使您的查询变得简单且性能良好


为了避免保存其他数据,您可以创建一个只包含ID的新表。使用触发器填充它并使其与主表保持一致。

存储过程可能会更好,因为它可以将ID替换到查询中。因此,您的意思是不使用视图,而是直接使用union。。。这肯定行得通。