SQL优化 - 根据列值加入不同的表

时间:2012-05-08 04:27:24

标签: mysql sql optimization

我有一个表,其中包含一个充当“标志”的列,用于决定从哪个表中提取附加信息(即值1从table1中拉出,2从table2中取出,等等)。通常我会使用索引/键加入表。但是,我可以加入的表包含可以归一化为单独表的信息,这使我能够使用列来决定要加入哪个表。

所以这是我的问题,基于此列中产生的值加入不同表的最有效方法是什么?

以下是我知道如何完成此任务的两种方式。我很确定它们都不是最佳解决方案:

  1. 从主表中提取信息(包含决定要加入哪个表的列值),然后通过我的应用程序中的代码发送其他查询以获取其余信息。

  2. 加入疯狂,返回每个表的列(即使未使用)。然后,通过我的代码,忽略不需要的表的空值。

3 个答案:

答案 0 :(得分:1)

绝对不是选项2.如果您不需要数据,请不要检索它。简单。当您不需要数据时,加入表(特别是大表)会非常低效。您可以使用选项1或使用动态SQL来构建查询。然后我会将一些测试用例放在一起并运行执行计划以查看查询的执行情况。

答案 1 :(得分:1)

根据其他表的内容,我建议使用UNION - 返回的列需要在每个查询中相同。所以你可以这样做:

SELECT table1.title, tabel2.text FROM table1 INNER JOIN table2 ON table1.id=table2.id WHERE table1.key='2'
UNION
SELECT table1.title, tabel3.text FROM table1 INNER JOIN table3 ON table1.id=table3.id WHERE table1.key='3'

(调整SQL以确保它与您的架构匹配,并确实避免我添加的任何错误)

答案 2 :(得分:1)

我认为有可能:

create table a (id integer, flag boolean);
create table b (id integer, value_b varchar(30));
create table c (id integer, value_c varchar(30));

insert into a values (1, true), (2, false);
insert into b values (1, 'Val 1'), (2, 'Val 2');
insert into c values (1, 'C 1'), (2, 'C 2');

select a.id,
       case when a.flag then b.value_b else c.value_c end AS value
  from a
  left join b using (id)
  left join c using (id);

你可以try it out

当然有限制:

  • 列数是固定的,因此如果应省略某些值,则应选择NULL s;
  • 您必须为每列写一个CASE ... END;
  • 你应该提前知道所有已加入的表格;
  • 表现可能不是最好的。