2013-10-09 9 views
4

Мне действительно нужна помощь, ускоряющая следующий запрос в SQL Server. Прямо сейчас у меня это как представление, но мне все равно, является ли это представлением или функцией, мне просто нужно вернуть набор записей в интерфейс MS Access. Запрос выполняется 11 секунд, но со всеми циклами, которые он проходит, мне нужно это до 3 или менее секунд. Я пытался индексировать представление, которое у меня есть сейчас, но, к сожалению, я не могу использовать функцию AVG или использовать предложение HAVING, если я собираюсь индексировать что-либо.Ускорение хранимой процедуры SQL Server

SELECT tblFi.fldFN 
    ,tblFc.fldFC 
    ,tblFc.fldCity 
    ,tblFc.fldState 
    ,tblFi.fldIN 
    ,tblAPL.fldPK 
    ,tblAPL.fldCI 
    ,AVG(tblAPD.fldND) AS fldND 
FROM tblAPD 
INNER JOIN tblAPL ON tblAPD.fldLK = tblAPL.fldLID 
INNER JOIN tblUA ON tblAPD.fldUAK = tblUA.fldUAID 
INNER JOIN tblUL ON tblUA.fldULK = tblUL.fldULID 
INNER JOIN tblFi ON tblUL.fldFK = tblFi.fldFID 
INNER JOIN tblFc ON tblFi.fldFAC = tblFc.fldFacID 
GROUP BY tblFi.fldFN 
    ,tblFc.fldFac 
    ,tblFc.fldCity 
    ,tblFc.fldState 
    ,tblFi.fldIN 
    ,tblAPL.fldPK 
    ,tblAPL.fldCI 
    ,tblAPL.fldPG 
    ,tblAPD.fldIG 
HAVING (tblAPL.fldCI <> 0) 
AND (AVG(tblAPD.fldND) IS NOT NULL) 
AND (tblAPL.fldPG = 1) 
AND (tblAPD.fldIG = 0) 

Ниже приведены таблицы (I включены только имена псевдо для столбцов, указанных в запросе, а затем FLD1, fld2, fld3 для тех, которые не имеют никакого отношения) ...

tblAPL - 4,5 млн ряды, кластерный индекс на fldLID

fldLID... INT 
fld1... FLOAT 
fldCI... FLOAT 
fldPK... BIGINT 
fldPG... TINYINT 
fld2... TINYINT 
fld3... TINYINT 
fld4... NVARCHAR(15) 
fld5... DATETIME 
fld6... TINYINT 
fld7... TINYINT 

tblAPD - 12 миллионов строк, кластерный индекс на fldDID

fldND... FLOAT 
fldLK... INT 
fldUAK... INT 
fldIG... TINYINT 
fld1... SMALLINT 
fld2... SMALLINT 
fld3... SMALLINT 
fld4... NVARCHAR(20) 
fld5... TINYINT 
fldDID... INT 

tblUA - 850000 строк, кластерный индекс на fldUAID

fldULK... INT 
fldUAID... INT 
fld1... NVARCHAR(10) 
fld2... INT 
fld3... NVARCHAR(15) 
fld4... INT 
fld5... TINYINT 
fld6... NVARCHAR(10) 
fld7... INT 
fld8... TINYINT 
fld9...TINYINT 
fld10...TINYINT 

tblUL - 200 000 строк, кластерный индекс на fldULID

fldULID... INT 
fldFK... INT 
fld1... INT 
fld2... INT 
fld3... INT 
fld4... NVARCHAR(15) 
fld5... DATETIME 
fld6... DATETIME 
+5

* Я пробовал несколько вещей, но ничего не помогло. * Было бы полезно рассказать нам, что вы пробовали, и почему они не работали, прежде чем мы расскажем вам посмотреть планы выполнения и определить новые, подходящие индексы ИЛИ использовать материализованное представление, чтобы мы не тратили впустую ваше время ... и наше. –

+0

Прежде всего, что такое СУБД? Если MS SQL означает «Microsoft SQL Server», можете ли вы рассказать нам, что такое кластеризованный индекс для каждой таблицы? –

+0

Отредактировано, чтобы попытаться сделать его более понятным. СУБД - это MS SQL Server 2008. – codingManiac

ответ

0

Вы можете начать с добавления SET NOCOUNT ON; Это должно ускорить его.

0

Вы пытались изменить предложение HAVING в простое предложение WHERE? Единственная часть, которую вы действительно не можете переместить в предложение WHERE, - это вторая строка (одна с выражением AVG), правильно? Это может ускорить его, поскольку критерии HAVING не оцениваются до тех пор, пока не будет сформирован весь набор результатов.

0
SELECT tblFi.fldFN 
    ,tblFc.fldFC 
    ,tblFc.fldCity 
    ,tblFc.fldState 
    ,tblFi.fldIN 
    ,tblAPL.fldPK 
    ,tblAPL.fldCI 
    ,AVG(tblAPD.fldND) AS fldND 
FROM tblAPD (NOLOCK) 
INNER JOIN tblAPL (NOLOCK) ON tblAPD.fldLK = tblAPL.fldLID 
INNER JOIN tblUA (NOLOCK) ON tblAPD.fldUAK = tblUA.fldUAID 
INNER JOIN tblUL (NOLOCK) ON tblUA.fldULK = tblUL.fldULID 
INNER JOIN tblFi (NOLOCK) ON tblUL.fldFK = tblFi.fldFID 
INNER JOIN tblFc (NOLOCK) ON tblFi.fldFAC = tblFc.fldFacID 
GROUP BY tblFi.fldFN 
    ,tblFc.fldFac 
    ,tblFc.fldCity 
    ,tblFc.fldState 
    ,tblFi.fldIN 
    ,tblAPL.fldPK 
    ,tblAPL.fldCI 
    ,tblAPL.fldPG 
    ,tblAPD.fldIG 
WHERE (tblAPL.fldCI <> 0) 
AND (tblAPL.fldCI = 1) 
AND (tblAPD.fldIG = 0) 
HAVING (AVG(tblAPD.fldND) IS NOT NULL) 

Сделать NON кластерный индекс по (fldCI) и (fldIG) Надеюсь, у вас есть индекс для всех внешних ключей.

+0

OP должен знать, что NOLOCK открывает его до возможности грязного чтения. – bhs

+0

да NOLOCK дает вам возможность грязных чтений, но это быстрее. – Frank

+0

быстрее по этой причине. – bhs

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