Запрос объединения в одной и той же таблице несколько раз

#sql #tsql

Вопрос:

 Select c.id
from Customer c
     inner join Orders o on (o.cid=c.id)
     where c.companyid=?
union 
     Select c.id
     Customer c
     inner join RecentOrder ro on (ro.cid=c.cid)
     where c.companyid=?
 

Как можно повысить производительность запроса? В моей таблице клиентов содержится 50 тыс. данных для одного «идентификатора компании», поэтому таблица заказов и последних заказов также содержит огромные данные. Как я могу повысить производительность запросов?

Комментарии:

1. Производительность сейчас даже не является проблемой; это неверный запрос.

2. СОЮЗУ требуется один ВЫБОР до и один ВЫБОР после.

3. И ORDER является зарезервированным словом в SQL, en.wikipedia.org/wiki/SQL_reserved_words . Необходимо определить как "ORDER" . SQL Server также принимает [ORDER] .

4. вместо союза se союз все как союз влияет на производительность. Объединение пытается отфильтровать отдельные записи из результата.

5. @EpicChen да, это для обоих

Ответ №1:

Я бы предложил использовать or :

 select c.id 
from Customer c 
where exists (select 1
              from Order o
              where o.cid = c.id
             ) or
      exists (select 1
              from RecentOrder o
              where o.cid = c.id and c.companyid = ?
             );
 

Для подзапросов вам нужны индексы на Orders(cid) и RecentOrders(cid) .

Комментарии:

1. Время выполнения с использованием этого запроса намного больше, чем у опубликованного.

2. @Techie321 . . . У вас есть рекомендуемые индексы?

Ответ №2:

Мое предложение состояло бы в том, чтобы использовать union all, если вы уверены, что эти запросы вернут идентичные записи. Это улучшит производительность, так как у вас будет больше записей. У Union all есть хит производительности, поскольку он выбирает уникальные записи участников.

В вашем запросе есть синтаксическая ошибка, которую я исправил в этом ответе. Если вы хотите отфильтровать записи объединения, перейдите к производной таблице после получения записей в запросе «Объединение всех».

       Select 
        c.id
      from Customer c
       inner join Order o 
            on o.cid=c.id
       where c.companyid=''

       union  all

       Select 
        c.id
      from Customer c
        inner join RecentOrder ro 
          on ro.cid=c.cid
         where c.companyid=''
 

Комментарии:

1. какая разница, я этого не понял

2. Союз и все Союзы? Union пытается отфильтровать отдельные записи, которые добавят дополнительный прирост производительности в запрос, так как у вас более 50 тысяч записей.

3. Есть несколько других советов по повышению производительности, таких как создание индексов для столбцов фильтра и использование без блокировки или включения индексов. это зависит от ваших требований. Если вы можете дать мне таблицу с данными, я могу дать вам лучшее объяснение, здесь я добавил совет использовать UNION или UNION ALL. @Techie321

4. используемое объединение и объединение все еще оказывают незначительное влияние на производительность запросов

5. Можете ли вы добавить некоторые скрипты данных и таблиц. Так что я могу попробовать. Попробуйте использовать некластеризованный индекс при условии where, если это первичный ключ, это не требуется. Мне нужно просмотреть таблицы и примеры данных. @Techie321

Ответ №3:

Добавьте некластеризованный индекс в [Customer] таблицу, он будет улучшен за счет поиска и сокращения поиска по полю. Однако это не может избежать сканирования на [Order] и [RecentOrder] . Если вы установили отношения между этими таблицами, оптимизатор sql может работать нормально.

     CREATE NONCLUSTERED INDEX [IX_Companyid_Customerid] ON [dbo].[Customer]
    (
        [companyid] ASC
    )
    INCLUDE ([id])
    GO
 

Это пример кода в виде mssql.

Комментарии:

1. В среде sql management studio уже создан индекс, как указано в плане выполнения

2. Не могли бы вы предоставить скриншот фактического плана выполнения?