У меня есть старый вид, который занимает 4 минуты для запуска, меня попросили ускорить его. FROM выглядит следующим образом:Ускорение работы представления
FROM TableA
CROSS JOIN ViewA
INNER JOIN TableB on ViewA.Name = TableB.Name
AND TableA.Code = TableB.Code
AND TableA.Location = TableB.Location
WHERE (DATEDIFF(m, ViewA.SubmitDate, GETDATE()) = 1) -- Only pull last months rows
Таблица А имеет около 99k строк, ViewA имеет около 2000 строк и TableB имеет около 101К строк. Я думаю, проблема в INNER JOIN, потому что я удаляю его, запрос занимает 1 секунду.
Моя первая мысль заключалась в том, чтобы увидеть, могу ли я уменьшить количество строк в ViewA, разбив все на CTE, но это сделало нулевой эффект. Я думаю, мне нужно индексировать TableB, потому что это просто куча varchars, которая используется в соединениях. Теперь я меняю его на временные таблицы, чтобы индексировать его. Я не могу изменить основные таблицы и представления. Являются ли индексные таблицы temp хорошим способом, или есть лучшее решение.
Редактировать, чтобы добавить информацию о существующих индексах. Единственное, с индексом на нем прямо сейчас - TableA.Id, который является PK и кластеризованным индексом. TableB имеет поле Id, но это не PK. ViewA не индексируется.
Изменить еще раз, чтобы исправить некоторую структуру. SubmitDate находится в представлении, а не в таблице.
Вот очень основная структура:
CREATE TABLE TableA
(
Id int NOT NULL PRIMARY KEY,
Section varchar(20) NULL,
Code varchar(20) NULL
)
CREATE TABLE TableB
(
Id int NOT NULL PRIMARY KEY,
Name varchar(20) NULL,
Code varchar(20) NULL,
Section varchar(20) NULL
)
CREATE TABLE TableC
(
Id int NOT NULL PRIMARY KEY,
Name varchar(20) NULL,
SubmitDate DateTime NOT NULL
)
CREATE TABLE TableD
(
Id int NOT NULL PRIMARY KEY,
Section varchar(20) NULL
)
CREATE VIEW ViewA
AS
SELECT c.Section, d.Name, c.SubmitDate
FROM TableC c
JOIN TableD d ON a.Id = b.Id
Почему «CROSS JOIN»? Есть ли в «TableA.SubmitDate» индекс? Даже если это не так, [прекратите использовать аргументы против него] (http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/16/bad-habits-to-kick-mishandling-date- range-queries.aspx) (также [прекратить использование сокращения] (http://sqlblog.com/blogs/aaron_bertrand/archive/2011/09/20/bad-habits-to-kick-using-shorthand-with-date- time-operations.aspx)) и try> = начало последнего месяца и <начало этого месяца. Существуют ли какие-либо индексы на любом из этих столбцов, используемых для соединения, кроме первичных ключей? –
(я показываю простые способы расчета начальных периодов [здесь] (http://sqlblog.com/blogs/aaron_bertrand/archive/2011/09/22/sql-server-v-next-denali-will-you-use -eomonth.aspx) и [здесь] (http://sqlperformance.com/2013/09/t-sql-queries/datediff-bug), а последний показывает ошибку, которая должна побуждать вас прекратить использование 'DATEDIFF' в предикаты в любом случае.) –
См. редактирование ключей и индексов. – BattlFrog