Mysql 需要有关涉及多个表的SQL查询的帮助-连接不是选项

Mysql 需要有关涉及多个表的SQL查询的帮助-连接不是选项,mysql,Mysql,这是我正在尝试运行的查询。它不能很好地扩展,我想知道这里是否有人能告诉我哪里可以改进。我不将w加入r和I,因为我需要显示I中在w中未表示的行。我试过左键,但效果不太好。这更好,但还不理想。这三张桌子都很大。所有三个都在我加入并选择的字段上建立索引 任何评论、建议或建设性批评都将不胜感激 编辑添加: 我应该在我的原始问题中提出这一点。这是SQLYog返回的解释 SELECT i.*, i.id IN ( SELECT id FROM w WHERE w.status='active'

这是我正在尝试运行的查询。它不能很好地扩展,我想知道这里是否有人能告诉我哪里可以改进。我不将w加入r和I,因为我需要显示I中在w中未表示的行。我试过左键,但效果不太好。这更好,但还不理想。这三张桌子都很大。所有三个都在我加入并选择的字段上建立索引

任何评论、建议或建设性批评都将不胜感激

编辑添加:


我应该在我的原始问题中提出这一点。这是SQLYog返回的解释

SELECT i.*, i.id IN (
  SELECT id
  FROM w 
  WHERE w.status='active') AS wish 
FROM i
INNER JOIN r ON i.id=r.id
WHERE r.member_id=1 && r.status='active' 
ORDER BY wish DESC 
LIMIT 0,50

编辑le dorfier-更多评论

我应该提到w的键是(member_id,id)。所以每个id可以在w中存在多次,我只想知道它是否存在


请张贴解释清单。并解释表和列的含义

“愿望”似乎是一个布尔值,你是按它排序的吗


编辑:嗯,看起来它在做它被指示做的事情。凯德似乎在广泛地思考这一切可能意味着什么(他可能只是为了努力而值得投票),但我真的希望你告诉我们

胡乱猜测只会把每个人都弄糊涂(我敢肯定,包括你)


好的,根据新的信息,我(稍微不那么疯狂)猜测一下

你想为w中的每一场比赛排一行吗?或者只是为了知道i.id是否有活动的w记录?我假设了第二个答案,所以你不需要按顺序-无论如何,它只针对一个ID。因为您只返回i中的列,所以如果r中有多行,您只会得到重复的行


发布您希望得到的正确答案如何?

请发布解释列表。并解释表和列的含义

“愿望”似乎是一个布尔值,你是按它排序的吗


编辑:嗯,看起来它在做它被指示做的事情。凯德似乎在广泛地思考这一切可能意味着什么(他可能只是为了努力而值得投票),但我真的希望你告诉我们

胡乱猜测只会把每个人都弄糊涂(我敢肯定,包括你)


好的,根据新的信息,我(稍微不那么疯狂)猜测一下

你想为w中的每一场比赛排一行吗?或者只是为了知道i.id是否有活动的w记录?我假设了第二个答案,所以你不需要按顺序-无论如何,它只针对一个ID。因为您只返回i中的列,所以如果r中有多行,您只会得到重复的行

发布你希望得到的正确答案怎么样?

你尝试过这个吗

SELECT i.*,  
    CASE WHEN EXISTS (SELECT 1 FROM w WHERE id = i.id AND w.status = 'active' THEN 1 ELSE 0 END) AS wish  
FROM i  
INNER JOIN r ON i.id = r.id AND r.status = 'active'  
WHERE r.member_id = 1
你试过这个吗

SELECT i.*,  
    CASE WHEN EXISTS (SELECT 1 FROM w WHERE id = i.id AND w.status = 'active' THEN 1 ELSE 0 END) AS wish  
FROM i  
INNER JOIN r ON i.id = r.id AND r.status = 'active'  
WHERE r.member_id = 1

我应该在我的原始问题中提出这一点。这是SQLYog返回的解释。
id |选择|类型|类型|可能的|键|键|列|参考|行|额外|
1 |主要| r |参考|成员| id,id |成员| id | 3 | const | 3120 |使用where;使用临时设备;使用文件排序
1 |初级| i | eq|u ref | id | id | 8 | r.id | 1 |

2 |依赖子查询| w |索引|子查询| id,status | id | 8 | func | 8 |使用where

我应该在我的原始问题中提出这个问题。这是SQLYog返回的解释。
id |选择|类型|类型|可能的|键|键|列|参考|行|额外|
1 |主要| r |参考|成员| id,id |成员| id | 3 | const | 3120 |使用where;使用临时设备;使用文件排序
1 |初级| i | eq|u ref | id | id | 8 | r.id | 1 |
2 |依赖子查询| w |索引|子查询| id,status | id | 8 | func | 8 |使用where

,其中x IN()
子查询的
内部联接
相同,通常,如果优化器没有将
中的
转换为
连接,则对子查询的连接通常会执行得更好-它应该:

SELECT i.*, w.id as wish FROM i
LEFT OUTER JOIN w ON i.id = w.id
  AND w.status = 'active'
WHERE i.id in (SELECT id FROM r WHERE r.member_id = 1 AND r.status = 'active')
ORDER BY wish DESC
LIMIT 0,50
如果您不需要不同的,则可能与此等效:

SELECT i.*
FROM i
INNER JOIN (
    SELECT DISTINCT id
    FROM w 
    WHERE w.status = 'active'
) AS wish 
    ON i.id = wish.id
INNER JOIN r
    ON i.id = r.id
WHERE r.member_id = 1 && r.status = 'active' 
ORDER BY wish.id DESC 
LIMIT 0,50
请发布您的模式

如果您使用愿望作为存在标志,请尝试:

SELECT i.*
FROM i
INNER JOIN w 
    ON w.status = 'active'
    AND i.id = wish.id
INNER JOIN r
    ON i.id = r.id
    AND r.member_id = 1 && r.status = 'active' 
ORDER BY i.id DESC 
LIMIT 0,50
您可以对
左连接
选择不同的子查询使用相同的技术。我假设您没有指定
w.member\u id
,因为您想知道是否有任何成员具有此属性?在这种情况下,一定要使用
选择DISTINCT
。您应该在
w
上的第一列有一个带有
id
的索引,以便执行以下操作:

SELECT i.*, CASE WHEN w.id IS NOT NULL THEN 1 ELSE 0 END AS wish
FROM i
INNER JOIN r
    ON i.id = r.id
    AND r.member_id = 1 && r.status = 'active' 
LEFT JOIN w 
    ON w.status = 'active'
    AND i.id = w.id
ORDER BY wish DESC 
LIMIT 0,50
其中x IN()
选择不同的子查询的
内部联接
相同,一般来说,如果优化器不将
中的
转换为
联接
,则对子查询的联接通常会执行得更好-它应该:

SELECT i.*, w.id as wish FROM i
LEFT OUTER JOIN w ON i.id = w.id
  AND w.status = 'active'
WHERE i.id in (SELECT id FROM r WHERE r.member_id = 1 AND r.status = 'active')
ORDER BY wish DESC
LIMIT 0,50
如果您不需要
不同的
,则可能与此等效:

SELECT i.*
FROM i
INNER JOIN (
    SELECT DISTINCT id
    FROM w 
    WHERE w.status = 'active'
) AS wish 
    ON i.id = wish.id
INNER JOIN r
    ON i.id = r.id
WHERE r.member_id = 1 && r.status = 'active' 
ORDER BY wish.id DESC 
LIMIT 0,50
请发布您的模式

如果您使用愿望作为存在标志,请尝试:

SELECT i.*
FROM i
INNER JOIN w 
    ON w.status = 'active'
    AND i.id = wish.id
INNER JOIN r
    ON i.id = r.id
    AND r.member_id = 1 && r.status = 'active' 
ORDER BY i.id DESC 
LIMIT 0,50
您可以对
左连接
选择不同的子查询使用相同的技术。我假设您没有指定
w.member\u id
,因为您想知道是否有任何成员具有此属性?在这种情况下,一定要使用
选择DISTINCT
。您应该在
w
上的第一列有一个带有
id
的索引,以便执行以下操作:

SELECT i.*, CASE WHEN w.id IS NOT NULL THEN 1 ELSE 0 END AS wish
FROM i
INNER JOIN r
    ON i.id = r.id
    AND r.member_id = 1 && r.status = 'active' 
LEFT JOIN w 
    ON w.status = 'active'
    AND i.id = w.id
ORDER BY wish DESC 
LIMIT 0,50
这似乎是一笔巨大的开支。您正在按计算列“
wish
”排序,该列不能从索引中受益。这迫使它使用文件排序(如解释所示),这意味着它将整个结果集写入磁盘,并使用非常慢的磁盘I/O对其进行排序

当您发布这样的问题时,您不应该期望人们猜测您是如何定义表和索引的。获取完整定义非常简单:

...
ORDER BY wish DESC 
LIMIT 0,50
然后将输出粘贴到问题中

不清楚您在“
wish
”列中的目的是什么。
中的“
”谓词是一个布尔表达式,因此