Простой SQL-запрос для небольших таблиц выполняется слишком долго

У меня есть запрос, выполнение которого занимает слишком много времени. Это просто и столы маленькие. Упрощенный запрос (но все еще медленный):

SELECT D.ID, C.Name, T.Name AS TownName
  FROM Documents D, Companies C, Towns T
  WHERE C.ID = D.Company AND T.ID = C.Town
  ORDER BY C.Name

Первичные ключи и внешние ключи между таблицами установлены правильно. Кроме того, индексируется столбец Companies.Name.

Я пытался использовать JOIN, перезапускать SQL Server, перестраивать индексы и т. д., но для выполнения на моем компьютере с SSD по-прежнему требуется около 40 секунд. Количество записей в таблицах Documents и Companies составляет всего 18К (в настоящее время они 1:1) и всего около 20 записей в таблице Towns.

С другой стороны, следующий запрос возвращает полностью те же записи, но его выполнение практически не занимает времени:

SELECT D.ID, C.Name, (SELECT Name FROM Towns WHERE ID = C.Town) AS TownName
  FROM Documents D, Companies C
  WHERE C.ID = D.Company
  ORDER BY C.Name

На мой взгляд, первый запрос должен быть еще быстрее, но я явно ошибаюсь. Кто-нибудь знает, что здесь происходит? Кажется, что индексы игнорируются при сортировке по столбцу в таблице, которая является мастером одного и деталью другого.


person adlabac    schedule 07.10.2015    source источник
comment
Почему вы до сих пор используете соединения в старом стиле ANSI-89? Вы должны использовать более новый синтаксис соединения, он существует уже более 20 лет. sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08/   -  person Sean Lange    schedule 07.10.2015
comment
что произойдет, если вы перейдете в Город › Компания › Документы.. используя соединения   -  person JamieD77    schedule 07.10.2015
comment
Если вам нужна реальная помощь, вам нужно предоставить фактический ddl, включая определения индексов, а также количество строк для таблиц. Фактический план выполнения тоже может помочь.   -  person Sean Lange    schedule 07.10.2015
comment
Вы смотрели план? Он должен сказать вам, на что тратятся ресурсы.   -  person Michael Gardner    schedule 07.10.2015


Ответы (2)


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

Обычно я иду от меньшего к большему, когда я не использую условия where. Итак, мой запрос будет выглядеть так:

Select  t.Name TownName,
        c.Name,
        d.Id
From    Towns t
        Join Companies c ON t.Id = c.Town
        Join Documents d ON c.Id = d.Company
Order By c.Name

Затем я бы удостоверился, что у компаний есть индекс по городу, а у документов есть и индекс по компании. 18 КБ записей могут занять некоторое время для отображения в окне вывода, но запрос должен быть довольно быстрым.

person JamieD77    schedule 07.10.2015
comment
Запрос был столь же медленным. Кроме того, добавление индекса для города не помогло, но добавление индекса для компании в таблицу документов сработало! Я (ошибочно) предположил, что внешнего ключа будет достаточно. Тем не менее, для меня загадка, почему другой запрос работает нормально, хотя это другая таблица. Кроме того, удаление таблицы Cities из запросов сделает запросы мгновенными. - person adlabac; 07.10.2015

что происходит, когда вы используете операторы соединения?

SELECT D.ID, C.Name, T.Name AS TownName
FROM Documents D
inner join Companies C on C.
inner join Towns T on T.ID = C.Town
ORDER BY C.Name

также попробуйте с заказом и без

person James    schedule 07.10.2015
comment
Как я уже упоминал, я попробовал INNER JOIN, как это, и это одинаково медленно: SELECT D.ID, C.Name, T.Name AS TownName FROM Companies C INNER JOIN Documents D ON C.ID = D.Company INNER JOIN Towns T ON T.ID = C.Town ORDER BY C.Name Я также пытался использовать Documents таблицу в WHERE, как вы предложили, но ничего не изменилось. Без ORDER это мгновенно. - person adlabac; 07.10.2015