【问题标题】:Optimization of a sql-query with exists使用存在优化 sql 查询
【发布时间】:2014-11-12 06:15:07
【问题描述】:

我有一张桌子:

+----+---------+-----------+--------------+-----------+
| id | item_id | attr_name | string_value | int_value |
+----+---------+-----------+--------------+-----------+
|  1 |       1 |         1 | prop_str_1   | NULL      |
|  2 |       1 |         2 | prop_str_2   | NULL      |
|  3 |       1 |         3 | NULL         | 2         |
|  4 |       2 |         1 | prop_str_1   | NULL      |
|  5 |       2 |         2 | prop_str_3   | NULL      |
|  6 |       2 |         3 | NULL         | 2         |
|  7 |       3 |         1 | prop_str_4   | NULL      |
|  8 |       3 |         2 | prop_str_2   | NULL      |
|  9 |       3 |         3 | NULL         | 1         |
+----+---------+-----------+--------------+-----------+

我想为属性选择具有特定值的 item_id。但是,由于需要对多个属性进行提取,这使情况变得复杂。我必须使用存在来做到这一点:

select *
  from item_attribute as attr
  where (name = 1 and string_value = 'prop_str_1')
  and exists
  (select item_id
  from item_attribute
  where item_id = attr.item_id and name = 2 and string_value = 'prop_str_2')

但是属性的数量可以增加,因此带有exists的嵌套查询会增加。 如何重写此查询以减少嵌套查询?

更新:

create table item_attribute(
    id int not null,
    item_id int not null,
    attr_name int not null,
    string_value varchar(50),
    int_value int,
    primary key (id)
);

insert into item_attribute values (1, 1, 1, 'prop_str_1', NULL);
insert into item_attribute values (2, 1, 2, 'prop_str_2', NULL);
insert into item_attribute values (3, 1, 3, NULL, 2);
insert into item_attribute values (4, 2, 1, 'prop_str_1', NULL);
insert into item_attribute values (5, 2, 2, 'prop_str_3', NULL);
insert into item_attribute values (6, 2, 3, NULL, 2);
insert into item_attribute values (7, 3, 1, 'prop_str_4', NULL);
insert into item_attribute values (8, 3, 2, 'prop_str_2', NULL);
insert into item_attribute values (9, 3, 3, NULL, 1);

【问题讨论】:

  • 为什么 2 个查询使用不同的表名?有两张桌子还是只有一张?最好也输入预期的输出,以便我们更好地回答您
  • @TheProvost 哦,这是一个错误!这是同一张桌子。我修好了。
  • 您编写的查询不会返回任何内容,因为您选择了两个具有不同 string_value 而不是 attr_name 的不同 attr_name 我认为您必须使用 attr_id 来返回一些结果,否则两个条件都将按照描述失败在你查询中
  • @DharmeshPorwal 不完全是。这些数据的第一个查询(条件:attr_name = 1 和 string_value = 'prop_str_1')返回 2 行 id 1 和 4 给定子查询,结果是 id 1 行
  • @NickMojarovskiy 您的查询工作正常......

标签: sql sql-server subquery query-optimization


【解决方案1】:

看看这是否适合你。它本质上做同样的事情......你的第一个限定符是给定的属性名称 = 1 和字符串 = 'prop_str_1',但随后再次以相同的 ID 自连接到属性表,但第二个属性和字符串

select 
      attr.*
   from 
      item_attribute attr
         JOIN item_attribute attr2
            ON attr.item_id = attr2.item_id
            and attr2.name = 2
            and attr2.string_value = 'prop_str_2'
   where 
          attr.name = 1 
      and string_value = 'prop_str_1'

我还会在 (name, string_value, item_id) 上为您的表创建一个索引,以提高 where 和 join 条件的性能。

【讨论】:

  • 是的,它会发球的!并且这个要求很好地扩展到了新的条件。谢谢!
猜你喜欢
  • 2012-09-18
  • 1970-01-01
  • 2019-03-30
  • 2021-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-10
相关资源
最近更新 更多