2015-04-23 8 views
0

У меня есть старый вид, который занимает 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 
+1

Почему «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> = начало последнего месяца и <начало этого месяца. Существуют ли какие-либо индексы на любом из этих столбцов, используемых для соединения, кроме первичных ключей? –

+0

(я показываю простые способы расчета начальных периодов [здесь] (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' в предикаты в любом случае.) –

+0

См. редактирование ключей и индексов. – BattlFrog

ответ

3

Один improovement является переписать где положение в sargable пункта. Добавить индекс SubmitDate, если нет индекса и изменения запросов к:

FROM TableA 
CROSS JOIN ViewA 
INNER JOIN TableB on ViewA.Name = TableB.Name 
    AND TableA.Code = TableB.Code 
    AND TableA.Location = TableB.Location 
WHERE 
TableA.SubmitDate >=DATEADD(MONTH,DATEDIFF(MONTH,0,GETDATE())-1,0) 
And TableA.SubmitDate < Dateadd(DAY, 1, DATEADD(MONTH, 
    DATEDIFF(MONTH, -1, GETDATE())-1, -1)) 

Также добавьте некластерные индексы Name, Code и Location колонн.

+0

Когда вы говорите, чтобы добавить индекс к этим столбцам, не нужно ли мне иметь доступ/разрешения для этих таблиц? (Я не). Или есть способ сделать индекс temp как часть запроса? – BattlFrog

+0

Приносим свои извинения, а SubmitDate - не в таблице. – BattlFrog

+0

Тогда тот, у кого есть разрешения, должен помочь вам. Вы также можете создавать индексы на представлении, но существует множество ограничений. –

Смежные вопросы