如何使用Row_Number()优化SQL查询性能以对SQL Server中的数百万条记录进行操作?

时间:2015-05-27 06:28:43

标签: sql sql-server

在我的项目中,我使用以下查询与SQL Server 2005中使用Row_Number()的分页机制来从包含数百万条记录的数据库中获取记录。当我执行此查询时,它需要大约1:25+秒来获取结果,我无法弄清楚我哪里出错了?我们如何优化此查询以在尽可能快的时间内获得预期结果,在第一页上显示n条记录并在分页操作进行时获取相应的记录?

这就是我们创建表格的方式:

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 '''+@FromDate+''' =''0'' THEN ''1970-01-01'' WHEN '''+@FromDate+''' = '''' THEN ''1970-01-01'' ELSE ''ValueCameFromVariable'' END) AND (CASE WHEN '''+@ToDate+''' = ''0'' THEN ''5000-01-01'' WHEN '''+@ToDate+''' = '''' THEN ''5000-01-01'' ELSE ''ValueCameFromVariable'' END)) ' 

+ 

' AND (('''+@QFid+''' = ''ALL'' AND mtid IN (select mtid FROM iftable)) OR ('''+@QFid+''' = ''Err'' AND mtid IN(9,15)) OR ('''+@QFid+''' = ''CLog'' AND mtid IN(9,15,14,50,56))) ' 

+ 

' AND sid = (CASE WHEN '''+@Sid+''' = ''ALL'' THEN sid WHEN '''+@Sid+''' = '''' THEN sid ELSE '''+@Sid+''' END) ' 

+ 

' AND bid = (CASE WHEN '''+@Bid+''' = ''ALL'' THEN bid WHEN '''+@Bid+''' = '''' THEN bid ELSE '''+@Bid+''' END) ' 

+ 

' AND fid = (CASE WHEN '''+@Fid+''' = ''ALL'' THEN fid WHEN '''+@Fid+''' = '''' THEN fid ELSE '''+@Fid+''' END) ' 

+ 

' AND stid = (CASE WHEN '''+@Stid+''' = ''ALL'' THEN stid WHEN '''+@Stid+''' = '''' THEN stid ELSE '''+@Stid+''' END)' 

+ 

' AND rfid = (CASE WHEN '''+@RFID+''' = ''0'' THEN rfid WHEN '''+@RFID+''' = '''' THEN rfid ELSE '''+@RFID+''' END) ' 

+ 

' AND frid = (CASE WHEN '''+@FRID+''' = ''0'' THEN frid WHEN '''+@FRID+''' = '''' THEN frid ELSE '''+@FRID+''' END) ' 

+ 

' AND fsid = (CASE WHEN '''+@FsID+''' = ''0'' THEN fsid WHEN '''+@FsID+''' = '''' THEN fsid ELSE '''+@FsID+''' END)' 

+ 

' AND mtid NOT IN ('+@Exclude+')) AS newTable WHERE newTable.RowNum BETWEEN ''1'' AND ''50''' 

exec sp_executesql @ExecuteDSQL

1 个答案:

答案 0 :(得分:1)

您的查询的问题是您按cdate desc,ctime desc,mid进行排序 但是你没有用于排序的所有列的索引。

您应该创建此索引以改善查询:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input style="margin-left:28px;" type="image" class="add_field_button" value="Add a new row" />
<br />From &rarr;
<input type="text" class="cal" name="fromhours" id="fromhours1" />:
<input type="text" class="cal" name="fromminutes" id="fromminutes1" /> | To &rarr;
<input type="text" class="cal" name="tohours" id="tohours1" />:
<input type="text" class="cal" name="tominutes" id="tominutes1" /> | Result &rarr;
<input type="text" class="cal" name="resulthours" id="resulthours1" />:
<input type="text" class="cal" name="resultminutes" id="resultminutes1" />
<br />
<br />
<div class="input_fields_wrap"></div>