почему некоторые столбцы замедляют выполнение запроса

Я использую SQL Server 2012.

Я пытаюсь оптимизировать запрос, который выглядит примерно так:

SELECT TOP 20 ta.id, 
              ta.name, 
              ta.amt, 
              tb.id, 
              tb.name, 
              tc.name, 
              tc.id, 
              tc.descr 
FROM   a ta 
       INNER JOIN b tb 
               ON ta.id = tb.id 
       INNER JOIN c tc 
               ON tb.id = tc.id 
ORDER  BY ta.mytime DESC 

Запрос занимает около 5-6 секунд. Имеются индексы для всех столбцов, используемых в соединениях. Таблицы имеют 500 тыс. записей.

Мой вопрос: когда я удаляю столбцы tc.name, tc.id и tc.descr из выбора, запрос возвращает результаты менее чем за секунду. Почему?


person Nik    schedule 22.01.2013    source источник
comment
Поскольку вы удаляете всю таблицу из JOIN. Вы должны начать с самой большой таблицы, затем JOIN к меньшим таблицам.   -  person Kermit    schedule 23.01.2013
comment
c часто пишут?   -  person MikeSmithDev    schedule 23.01.2013
comment
Если вы используете SQL Management Studio, вы можете запустить оптимизатор, чтобы увидеть план выполнения. Это может дать некоторое представление о том, в чем именно заключается проблема: simple-talk.com/sql/sql-training/the-sql-server-query-optimizer   -  person Wade    schedule 23.01.2013
comment
Вы должны показать нам определения таблиц и индексов. Для диагностики медленных запросов требуются полные определения таблиц и индексов, а не просто описание или парафраз. Возможно, ваши таблицы плохо определены. Возможно, индексы созданы неправильно. Возможно, у вас нет индекса в том столбце, который, как вы думали, у вас есть. Не видя определений таблиц и индексов, мы не можем сказать. Если вы знаете, как выполнить EXPLAIN, также укажите результаты в вопросе.   -  person Andy Lester    schedule 23.01.2013


Ответы (3)


Вам нужно опубликовать планы выполнения, чтобы действительно знать разницу.

Насколько мне известно, SQL Server не оптимизирует удаленные соединения. В конце концов, даже без столбцов в списке выбора соединения можно использовать для фильтрации и умножения количества строк.

Однако один шаг может быть пропущен. С переменными в select движку необходимо перейти к индексу и получить страницу с данными. Без переменных движку не нужно выполнять выборку. Это может незначительно склонить баланс оптимизатора от одного типа соединения к другому.

Вторая возможность просто связана со временем. Если вы выполнили запрос один раз, кэши страниц могут быть заполнены на компьютере. При втором запуске запрос выполняется намного быстрее просто потому, что данные находятся в памяти. Никогда не запускайте тайминги, если вы либо (1) не очищаете кеш между каждым вызовом, либо (2) не уверены, что кеш заполнен одинаково.

person Gordon Linoff    schedule 23.01.2013

У вас есть кластерные индексы? Если нет, вам следует создать кластеризованные индексы и выполнить целочисленный запрос и в основном столбцы первичного ключа.

Проверьте http://msdn.microsoft.com/en-us/library/aa933131(v=sql.80).aspx для кластерного индекса.

person Taicho    schedule 23.01.2013

Наконец-то я смог настроить запрос, добавив в таблицу дополнительный индекс. SQL-сервер не показывал/не подразумевал отсутствующий индекс, но я понял это, создав новый некластеризованный индекс для поля, которое присутствует в выборе.

Спасибо вам всем за то, что пришли за помощью.

@Wade, ссылка действительно полезна для понимания оптимизатора SQL.

person Nik    schedule 11.04.2013