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