• Как написать запрос, который будет считывать меньше данных?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Здесь временная таблица не нужна: все можно сделать одним запросом:
    select distinct c.CrossArticleId from Crosses c inner join Crosses f 
    on c.ArticleId=f.CrossArticleId where f.ArticleId=1

    А чтобы избежать сканирования всей таблицы, создайте (если их ещё нет)индексы по полям Crosses.ArticleId и Crosses.CrossArticleId - например, как в предыдущем ответе написано. И пусть работает и оптимизирует запрос планировщик: он кремниевый, и у него есть статистика по индексам. Если вдруг сомневаетесь в планировщике - посмотрите план выполнения запроса.
    Индексы - это ключевой момент: без них серверу придется сканировать всю таблицу.
    Ответ написан
    3 комментария
  • Как написать запрос, который будет считывать меньше данных?

    @Naiivi
    Запрос можно оптимизировать тремя способами:
    1) Использовать индексы по полям ArticleId и CrossArticleId в таблице Crosses;
    2) Использовать группировку по полю CrossArticleId во временной таблице @tempFlatCrosses, чтобы избежать дубликатов при соединении с таблицей Crosses;
    3) Использовать оператор EXISTS, вместо INNER JOIN, чтобы проверить наличие соответствующих записей в таблице Crosses, без возврата лишних данных.
    -- Создаем индексы по полям ArticleId и CrossArticleId в таблице Crosses
    CREATE INDEX idx_crosses_articleid ON Crosses (ArticleId);
    CREATE INDEX idx_crosses_crossarticleid ON Crosses (CrossArticleId);
    
    -- Достаем все строки, у которых ArticleId = 1 и группируем по CrossArticleId
    SELECT ArticleId, CrossArticleId
    INTO @tempFlatCrosses
    FROM Crosses
    WHERE ArticleId = 1
    GROUP BY CrossArticleId;
    
    -- Делаем выборку из таблицы Crosses, используя оператор EXISTS
    SELECT c.ArticleId
    FROM Crosses c
    WHERE EXISTS (
      SELECT 1
      FROM @tempFlatCrosses f
      WHERE c.CrossArticleId = f.CrossArticleId
    );
    Ответ написан
    1 комментарий