Mysql SQL-使用共享索引连接多个表
我有三个不同列的数据表(如果较小的联接工作得更快,请尝试在这些较小的步骤中执行 从这样的事情开始Mysql SQL-使用共享索引连接多个表,mysql,sql,join,pivot-table,Mysql,Sql,Join,Pivot Table,我有三个不同列的数据表(如果较小的联接工作得更快,请尝试在这些较小的步骤中执行 从这样的事情开始 CREATE TABLE my_table SELECT a.id, a.A1, a.A2, a.[rest of columns], b.B1, b.B2, b.[rest of columns], c.C1, c.C2, c.[rest of columns] FROM
CREATE TABLE my_table
SELECT
a.id,
a.A1,
a.A2,
a.[rest of columns],
b.B1,
b.B2,
b.[rest of columns],
c.C1,
c.C2,
c.[rest of columns]
FROM
table_A a
LEFT JOIN table_B b
ON a.id = a.id
LEFT JOIN table_C c
ON a.id = c.id
创建临时表我的表
挑选*
来自表A
左外联接表
表_A.id=表_B.id
然后
创建表格我的表格
挑选*
从我的桌子上
左外联接表
在my_table_AB.id=table_C.id上
另一件事是-你需要在这里加入左连接吗
由于它被标记为已解决,并且我们在讨论中找到了解决方案,我将把它放在这里仅供参考-缺少主键的问题。添加它后,它按预期工作。如果较小的连接工作得更快,请尝试在这些较小的步骤中执行
从这样的事情开始
CREATE TABLE my_table
SELECT
a.id,
a.A1,
a.A2,
a.[rest of columns],
b.B1,
b.B2,
b.[rest of columns],
c.C1,
c.C2,
c.[rest of columns]
FROM
table_A a
LEFT JOIN table_B b
ON a.id = a.id
LEFT JOIN table_C c
ON a.id = c.id
创建临时表我的表
挑选*
来自表A
左外联接表
表_A.id=表_B.id
然后
创建表格我的表格
挑选*
从我的桌子上
左外联接表
在my_table_AB.id=table_C.id上
另一件事是-你需要在这里加入左连接吗
由于它被标记为已解决,并且我们在讨论中找到了解决方案,我将把它放在这里仅供参考-缺少主键的问题。添加它后,它按预期工作。您可能正在三个表之间生成笛卡尔积。您可以使用以下公式计算结果集中的总行数:
select sum(a.cnt * coalesce(b.cnt, 1) * coalesce(c.cnt, 1))
from (select id, count(*) as cnt from a group by id) a left join
(select id, count(*) as cnt from b group by id) b
on a.id = b.id left join
(select id, count(*) as cnt from c group by id) c
on a.id = c.id;
我的猜测是,这个数字比您预期的要大得多。这是因为b
和c
对于某些id
s都有多行。您没有解释在这种情况下想要得到什么结果,因此很难为您的问题提供实际的解决方案。但这应该可以解释性能问题。You可能正在三个表之间生成笛卡尔积。您可以使用以下公式计算结果集中的总行数:
select sum(a.cnt * coalesce(b.cnt, 1) * coalesce(c.cnt, 1))
from (select id, count(*) as cnt from a group by id) a left join
(select id, count(*) as cnt from b group by id) b
on a.id = b.id left join
(select id, count(*) as cnt from c group by id) c
on a.id = c.id;
我的猜测是,这个数字比您预期的要大得多。这是因为b
和c
对于某些id
s都有多行。您没有解释在这种情况下想要得到什么结果,因此很难为您的问题提供实际的解决方案。但这应该可以解释性能问题。由于您试图从select创建表,因此可能会阻塞。问题是新表中的列名不能重复。您可能需要显式,例如
CREATE TABLE my_table
SELECT
a.id,
a.A1,
a.A2,
a.[rest of columns],
b.B1,
b.B2,
b.[rest of columns],
c.C1,
c.C2,
c.[rest of columns]
FROM
table_A a
LEFT JOIN table_B b
ON a.id = a.id
LEFT JOIN table_C c
ON a.id = c.id
对于500行,它应该几乎是即时的,因为您试图从select创建表,所以它可能会阻塞。问题是新表中不能有重复的列名。您可能需要显式,例如
CREATE TABLE my_table
SELECT
a.id,
a.A1,
a.A2,
a.[rest of columns],
b.B1,
b.B2,
b.[rest of columns],
c.C1,
c.C2,
c.[rest of columns]
FROM
table_A a
LEFT JOIN table_B b
ON a.id = a.id
LEFT JOIN table_C c
ON a.id = c.id
对于500行,它应该几乎是瞬时的因为我们需要所有3个表中的所有列基于所有表的id列连接,而不是左连接,我们不能在这里使用内部连接吗?因为我们需要所有3个表中的所有列基于所有表的id列连接,而不是左连接我们不能使用内部连接吗re?您需要获取表的所有列吗?否则您不需要使用select*
@D-Shih是不幸的是,我确实需要所有列:(请提供SHOW CREATE TABLE
是否需要获取表的所有列?否则不需要使用select*
@D-Shih是不幸的是,我确实需要所有列:(请提供SHOW CREATE TABLE
谢谢Adam!当以较小的步骤完成时,第一部分速度很快~5分钟,但就我所尝试的而言,第二部分仍然需要很长时间(1小时以上,我终止了查询)。我想我需要左加入
?你有什么建议吗?我可以预料到你会尝试:)当您以不同的顺序执行此操作时,这些时间是否相同?例如,先用C连接表A,然后用B连接表A,或者先用C和B连接表A,然后用A?和左连接
,仅当您在表A中有一些行在表B中没有匹配行时才需要。如果不是这种情况,您应该使用内部连接
。您是否正确地使用了在这些表上创建主键和外键?如果哪怕一个值都需要很长时间,这表明它可能正在进行一些表扫描,而不是使用索引。感谢Adam!当以较小的步骤完成时,第一部分速度很快~5分钟,但就我所尝试的,第二部分仍然需要很长时间(1小时以上,我终止了查询).我想我需要左键加入
?你有什么建议吗?我本以为你会这么做:)当您以不同的顺序执行此操作时,这些时间是否相同?例如,先用C连接表A,然后用B连接表A,或者先用C和B连接表A,然后用A?和左连接
,仅当您在表A中有一些行在表B中没有匹配行时才需要。如果不是这种情况,您应该使用内部连接
。您是否正确地使用了在这些表上创建主键和外键?如果哪怕只需要一个值都需要很长时间,这表明它可能正在执行一些表扫描,而不是使用索引。表A类似于一个内容表-我需要表A中的所有行:(CREATE table#estreable(-All columns definition在这里--将Id作为索引列Id INT主键聚集)插入到#tettable(--在这里列出所有必需的列)SELECT——在这里列出表A上的表A左联接表B中的所有必需列。表A.id=表B.id选择*表A上的表A左联接表C中的表A=表C.id;表A类似于一个内容表-我需要表A中的所有行:(创建表#(-All columns definition here--Make Id as indexed columns Id INT PRIMARY KEY CLUSTERED)INSERT INTO#tentable(-List All required columns here)SELECT--List All required columns here FROM table_A LEFT JOIN table_B ON table_A.Id=table
id select_type table type posibble_keys key key_len ref rows filtered Extra
1 SIMPLE table_A ALL (Null) (Null) (Null) (Null) 59670 100
1 SIMPLE table_B ALL (Null) (Null) (Null) (Null) 39776 100 Using; Using join buffer (Block Nested Loop) where
1 SIMPLE table_C ALL (Null) (Null) (Null) (Null) 50208 100 Using; Using join buffer (Block Nested Loop) where
select sum(a.cnt * coalesce(b.cnt, 1) * coalesce(c.cnt, 1))
from (select id, count(*) as cnt from a group by id) a left join
(select id, count(*) as cnt from b group by id) b
on a.id = b.id left join
(select id, count(*) as cnt from c group by id) c
on a.id = c.id;
CREATE TABLE my_table
SELECT
a.id,
a.A1,
a.A2,
a.[rest of columns],
b.B1,
b.B2,
b.[rest of columns],
c.C1,
c.C2,
c.[rest of columns]
FROM
table_A a
LEFT JOIN table_B b
ON a.id = a.id
LEFT JOIN table_C c
ON a.id = c.id