Проблема производительности перекрестного соединения

avatar
SqlGeek
8 апреля 2018 в 09:22
137
2
3

У меня есть следующий запрос, который выполняется очень медленно.

SELECT  A.city_id
            , FIRST_Hotel_By_City.hotel_name        
    FROM    hotel AS A  
            CROSS APPLY
            (
                SELECT  TOP 1 I.*
                FROM    hotel AS I
                WHERE   A.city_id = I.city_id
                ORDER   BY I.created_date ASC , hotel_name ASC
            ) FIRST_Hotel_By_City
    GROUP BY A.city_id
            , FIRST_Hotel_By_City.hotel_name
            , FIRST_Hotel_By_City.created_date
    ORDER BY A.city_id

У меня есть приведенный ниже некластеризованный индекс для City_id

CREATE NONCLUSTERED INDEX ix_cityid
  ON hotel(city_id )
  include (created_date, hotel_name) 

Может кто-нибудь помочь, если мы можем оптимизировать его дальше. Ниже приведены статистика и план выполнения запроса.

Статистика , План выполнения

Источник

Ответы (2)

avatar
Martin Smith
8 апреля 2018 в 11:26
0

Для каждого city_id вы пытаетесь вернуть hotel_name отеля, заказанного сначала created_date ASC, hotel_name ASC.

Вы можете использовать (Демо)

SELECT city_id,
       MIN(created_date) AS created_date,
       SUBSTRING(MIN(STR(DATEDIFF(DAY,'0001-01-01',created_date)) + hotel_name), 11, 8000)
FROM   hotel
GROUP  BY city_id 

который дает простой план выполнения с одним сканированием индекса.

enter image description here

avatar
PSK
8 апреля 2018 в 09:41
1

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

   SELECT DISTINCT city_id,hotel_name  FROM
    (
        SELECT A.city_id,
        (
         SELECT TOP 1 hotel_name FROM hotel I  WHERE   A.city_id = I.city_id
         ORDER BY  I.created_date ASC , hotel_name ASC
        ) AS hotel_name
        FROM hotel  A
    ) T