Альтернатива для объединения в SQL, где-предложение - PullRequest
1 голос
/ 22 июня 2011

в where предложении, которое я использую как

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

, для выполнения которого union.

требуется время. Пожалуйста, предоставьте другую альтернативу для повышения производительности моего запроса

Ответы [ 5 ]

5 голосов
/ 22 июня 2011

а как же

select name from products
where id in (select product_id from orders)
    or id = 1
4 голосов
/ 22 июня 2011

A union удаляет дубликаты, и SQL Server, к сожалению, может не обнаружить, что такое удаление не требуется, когда результат union используется в предикате IN.

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

UNION ALL говорит, что дубликаты разрешены, поэтому это позволит избежать дорогостоящего этапа удаления дубликатов.Даже если вы можете подумать, что, поскольку вторая часть объединения имеет только одно значение, проверка дубликатов должна быть быстрой, это не так.UNION говорит, что все дубликаты должны быть удалены.Он также должен удалить все повторяющиеся идентификаторы product_ids из первой части запроса.


Я только что провел несколько быстрых тестов и обнаружил одно повторение, в котором оптимизатор недостаточно умен, чтобы избежатьудаление дубликатов, для версий 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
2 голосов
/ 22 июня 2011

Используйте следующий запрос. Самый эффективный из всего лота.

select name from products P
where P.id = 1 or 
exists 
(select TOP 1 '1' from orders O
where O.product_id = P.id)
1 голос
/ 22 июня 2011
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;
0 голосов
/ 15 сентября 2015

Сокращение общего совокупного времени процессора: 9 секунд, 900 мсек. Завершенная работа = job_1442292787903_0035 Запущены MapReduce: Олень

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...