2015-05-27 3 views
-1

В моем проекте я использую следующий запрос с механизмом подкачки с использованием Row_Number() в SQL Server 2005 для извлечения записей из базы данных, содержащей миллионы записей. Когда я выполняю этот запрос, для получения результатов требуется почти 1: 25 + секунд, я не могу понять, где я ошибаюсь? Как мы можем оптимизировать этот запрос, чтобы оживить ожидаемые результаты в кратчайшие сроки, отображая n записей на первой странице и получая соответствующие записи по мере продолжения операции подкачки?Как оптимизировать производительность SQL-запросов с помощью Row_Number() для работы с миллионами записей в SQL Server?

Это, как мы создаем таблицу:

CREATE TABLE [iftable] (
    [sid] [float] DEFAULT (0) NOT NULL , 
    [mid] [float] DEFAULT (0) NOT NULL , 
    [bid] [float] DEFAULT (0) NOT NULL , 
    [fid] [float] DEFAULT (0) NOT NULL , 
    [fsid] [float] DEFAULT (0) NOT NULL , 
    [ftep] [float] DEFAULT (0) NOT NULL , 
    [mtid] [float] DEFAULT (0) NOT NULL , 
    [mstr] [varchar] (1000) DEFAULT (' ') NOT NULL , 
    [urblb] [image] NULL , 
    [urcode] [float] DEFAULT (0) NOT NULL , 
    [cdate] [datetime] DEFAULT (getdate()) NOT NULL , 
    [ctime] [char] (9) DEFAULT (' ') NOT NULL , 
    [olevel] [float] DEFAULT (0) NOT NULL, 
    [cat] [varchar](30) DEFAULT (' ') NOT NULL, 
    [ukey1] [varchar](30) DEFAULT (' ') NOT NULL, 
    [ukey2] [varchar](30) DEFAULT (' ') NOT NULL, 
    [vk] [varchar](30) DEFAULT (' ') NOT NULL, 
    [scode] [float] DEFAULT (0) NOT NULL, 
    [sty] [float] DEFAULT (0) NOT NULL, 
    [extnsn] [varchar](10) DEFAULT ('') NOT NULL, 
    [pkey] [varchar] (30) DEFAULT (' ') NOT NULL, 
    [bexists] [smallint] DEFAULT (0) NOT NULL 
) ON [PRIMARY] 

CREATE UNIQUE INDEX [iftablekey01] ON [iftable]([pkey], [sid], [mid]) ON [PRIMARY] 
GO 

// Выбрать запрос по таблице создана

DECLARE @Sid nvarchar(30) 
DECLARE @Bid nvarchar(30) 
DECLARE @Fid nvarchar(30) 
DECLARE @Stid nvarchar(30) 
DECLARE @QFid nvarchar(30) 
DECLARE @FromDate nvarchar(30) 
DECLARE @ToDate nvarchar(30) 
DECLARE @RFID nvarchar(30) 
DECLARE @FRID nvarchar(30) 
DECLARE @FsID nvarchar(30) 
DECLARE @Exclude nvarchar(MAX) 
DECLARE @ExecuteDSQL nvarchar(MAX) 

--Here below all the values will be coming from different variables like @QFid = 'VarQfid' 

SET @Sid = '' IF(@Sid = '*') SET @Sid = 'ALL' 
SET @Bid = '' IF(@Bid = '*') SET @Bid = 'ALL' 
SET @Fid = '' IF(@Fid = '*') SET @Fid = 'ALL' 
SET @Stid = '' IF(@Stid = '*') SET @Stid = 'ALL' 
SET @QFid = 'ALL' 
SET @FromDate = '' 
SET @ToDate = '' 
SET @RFID = '' 
SET @FRID = '' 
SET @FsID = '' 
SET @Exclude = '' IF(@Exclude = '') SET @Exclude = '100' 

SET @ExecuteDSQL = 'SELECT * FROM (SELECT *, Row_Number() over(order by cdate desc,ctime desc,mid desc) as rowNum from iftable where pkey=''ABC''' 

+ 

' AND (cdate BETWEEN (CASE WHEN '''[email protected]+''' =''0'' THEN ''1970-01-01'' WHEN '''[email protected]+''' = '''' THEN ''1970-01-01'' ELSE ''ValueCameFromVariable'' END) AND (CASE WHEN '''[email protected]+''' = ''0'' THEN ''5000-01-01'' WHEN '''[email protected]+''' = '''' THEN ''5000-01-01'' ELSE ''ValueCameFromVariable'' END)) ' 

+ 

' AND (('''[email protected]+''' = ''ALL'' AND mtid IN (select mtid FROM iftable)) OR ('''[email protected]+''' = ''Err'' AND mtid IN(9,15)) OR ('''[email protected]+''' = ''CLog'' AND mtid IN(9,15,14,50,56))) ' 

+ 

' AND sid = (CASE WHEN '''[email protected]+''' = ''ALL'' THEN sid WHEN '''[email protected]+''' = '''' THEN sid ELSE '''[email protected]+''' END) ' 

+ 

' AND bid = (CASE WHEN '''[email protected]+''' = ''ALL'' THEN bid WHEN '''[email protected]+''' = '''' THEN bid ELSE '''[email protected]+''' END) ' 

+ 

' AND fid = (CASE WHEN '''[email protected]+''' = ''ALL'' THEN fid WHEN '''[email protected]+''' = '''' THEN fid ELSE '''[email protected]+''' END) ' 

+ 

' AND stid = (CASE WHEN '''[email protected]+''' = ''ALL'' THEN stid WHEN '''[email protected]+''' = '''' THEN stid ELSE '''[email protected]+''' END)' 

+ 

' AND rfid = (CASE WHEN '''[email protected]+''' = ''0'' THEN rfid WHEN '''[email protected]+''' = '''' THEN rfid ELSE '''[email protected]+''' END) ' 

+ 

' AND frid = (CASE WHEN '''[email protected]+''' = ''0'' THEN frid WHEN '''[email protected]+''' = '''' THEN frid ELSE '''[email protected]+''' END) ' 

+ 

' AND fsid = (CASE WHEN '''[email protected]+''' = ''0'' THEN fsid WHEN '''[email protected]+''' = '''' THEN fsid ELSE '''[email protected]+''' END)' 

+ 

' AND mtid NOT IN ('[email protected]+')) AS newTable WHERE newTable.RowNum BETWEEN ''1'' AND ''50''' 

exec sp_executesql @ExecuteDSQL 
+0

Я думаю, что его проблема индексов. можете ли вы отправить SQL-запрос создания таблицы и индексы? – Tirma

+0

@Tirma, да конечно я буду ... –

+0

@ Тирма, пожалуйста, посмотрите, я изменил вопрос. –

ответ

1

проблема с вашим запросом вы сортировкой по CDate по алфавиту, CTIME по алфавиту, в середине , но у вас нет индексов по всем столбцам, которые вы используете для сортировки.

Вы должны создать этот индекс для улучшения вашего запроса:

CREATE CLUSTERED INDEX [_dta_index_iftable_c_8_205243786__K11D_K12D_K2D] ON [dbo].[iftable] 
(
    [cdate] DESC, 
    [ctime] DESC, 
    [mid] DESC 
)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY] 
+0

Я попробую это и вернусь к вам, спасибо. –

+0

Еще одна вещь .... вместо того, чтобы строить строку в переменной ExecuteDSQL, а затем вызывать sp_executesql, я думаю, что ее намного лучше выполнить запрос напрямую. только в качестве примера, вместо того, чтобы использовать SET ExecuteDSQL = 'SELECT * FROM A' ехес sp_executesql ExecuteDSQL просто использовать выберите * от A Он будет работать !! – Tirma

+0

, он отлично работает в SQL Server Management Studio, но занимает гораздо больше времени от браузера. –