简体   繁体   English

SQL where子句中联合的替代方法

[英]Alternative for union in SQL where-clause

in where clause i am using like where子句中,我使用像

SELECT name 
  FROM products 
 WHERE id IN (
           SELECT product_id 
             FROM orders 
            UNION 
           SELECT 1);

it taking time to perform union . 进行union需要时间。

please provide some other alternative to improve my query performance 请提供其他选择来改善我的查询性能

what about 关于什么

select name from products
where id in (select product_id from orders)
    or id = 1

A union removes duplicates, and SQL Server may unfortunately not be able to spot that such removal is not required when the result of the union is being used in an IN predicate. union删除重复项,并且不幸的是,当在IN谓词中使用union的结果时,SQL Server可能无法发现不需要这种删除。

SELECT name 
  FROM products 
 WHERE id IN (
           SELECT product_id 
             FROM orders 
            UNION ALL
           SELECT 1);

UNION ALL says that duplicates are allowed, so it will avoid the expensive step of removing duplicates. UNION ALL表示允许重复,因此可以避免删除重复项的昂贵步骤。 Even though you may think that, because the second part of the union only has one value, the duplicate check should be quick, this isn't so. 即使您可能会认为,由于联合的第二部分只有一个值,所以重复检查应该很快,但事实并非如此。 UNION says that all duplicates must be eliminated. UNION表示必须消除所有重复项。 It has to eliminate all the duplicate product_ids from the first part of the query also. 它也必须从查询的第一部分中消除所有重复的product_id。


I've just done a few quick tests, and found one repro where the optimizer isn't smart enough to avoid duplicate removal, for versions 2000, 2005, 2008. All 3 show a query plan that shows a distinct sort being used after concatenation between a table scan (of #IDs ) and a constant scan: 我刚刚进行了一些快速测试,发现了一个repro,其中优化程序不够智能,无法避免重复删除,适用于2000、2005、2008版本。所有这3个查询都显示了一个查询计划,该查询计划显示了级联后使用的独特排序在表扫描( #IDs )和恒定扫描之间:

create table #IDs (
    ID int not null
)
go
insert into #IDs (ID)
select 1 union all
select 1 union all
select 2 union all
select 2 union all
select 3
go
select * from sysobjects where id in (select ID from #IDs union select 1)
go

Use the following query. 使用以下查询。 Most efficient of the lot. 最有效的。

select name from products P
where P.id = 1 or 
exists 
(select TOP 1 '1' from orders O
where O.product_id = P.id)
select p1.name from products as p1
    inner join orders as o on o.product_id = p1.id
union
select p2.name from products as p2 where p2.id = 1;

减少总的累积CPU时间:9秒900毫秒结束的作业= job_1442292787903_0035启动的MapReduce作业:Stag

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM