比方說,我有兩個表Company
(幾乎60K記錄)和Position
(近60萬條記錄)如何提高這個sql查詢性能?
Company
表:
CompanyID INT --PRIMARY KEY
CompanyName NVARCHAR(100)
CompanyType INT --Just can be (1,2,3,4,5,6)
Position
表:
PositionID INT --Primary key
PositionName NVARCHAR(100)
CompanyID INT --FK point to Company Table
WorkExperience INT --Just can be (1,2,3,4,5,6,7,8)
WorkType INT --Just can be (1,2)
CreateTime datetime
UpdateTime datetime
我創建了一個NONCLUSTERED INDEX
在Company
表上:
CREATE NONCLUSTERED INDEX [IX_1] ON [dbo].[Company]
(
[CompanyKind] ASC
)
INCLUDE ([CompanyName]) ON [PRIMARY]
GO
而且我已經創建了兩個NONCLUSTERED INDICES
ON的Position
表也:
CREATE NONCLUSTERED INDEX [IX_6] ON [dbo].[Position]
(
[CompanyID] ASC
)ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IX_8] ON [dbo].[Position]
(
[UpdateTime] ASC
) ON [PRIMARY]
我的分頁存儲過程是這樣的:
ALTER PROC [dbo].[spIndexJobList]
@KeyWord NVARCHAR(50) ,
@WorkExperience INT ,
@WorkType INT ,
@CompanyType INT ,
@PageSize INT ,
@PageNumber INT
[email protected] INT OUTPUT
AS
DECLARE @RowStart INT
DECLARE @RowEnd INT
DECLARE @SQL NVARCHAR(4000)
DECLARE @ParamDefinition NVARCHAR(2000)
SET @SQL = N'SELECT C.CompanyID,C.CompanyName,P.PositionName,P.PositionID,P.UpdateTime, Row_number() OVER (ORDER BY P.UpdateTime DESC) AS RowNumber FROM Company C INNER JOIN Position P ON C.CompanyID=P.CompanyID WHERE 1=1 '
IF @KeyWord!=''
SET @SQL = @SQL + ' AND PositionName LIKE @KeyWord'
IF @WorkExperience !=0
SET @SQL = @SQL + ' AND [email protected]'
IF @CompanyType != 0
SET @SQL = @SQL + ' AND [email protected]'
IF @WorkType !=0
SET @SQL = @SQL + ' AND [email protected]'
SET @ParamDefinition = ' @KeyWord NVarchar(50),
@WorkExperience INT,
@WorkType INT,
@CompanyType INT,
@PageSize INT,
@PageNumber INT'
IF @PageNumber > 0
BEGIN
SET @PageNumber = @PageNumber - 1
SET @RowStart = @PageSize * @PageNumber + 1 ;
SET @RowEnd = @RowStart + @PageSize - 1 ;
SET @SQL = '
WITH AllJobs
AS (' + @SQL
+ ')
SELECT *,(SELECT Count(RowNumber) FROM AllJobs) AS TotalRows FROM AllJobs WHERE RowNumber >='
+ STR(@RowStart) + ' AND RowNumber <= ' + STR(@RowEnd) + ''
EXECUTE sp_Executesql @SQL, @ParamDefinition,
@KeyWord, @WorkExperience,@WorkType,
@CompanyType, @PageSize, @PageNumber
END
我的調用語句是這樣的:
SET STATISTICS IO ON
DECLARE @return_value int
EXEC @return_value = [dbo].[spIndexJobList]
@KeyWord='',
@WorkExperience = 3,
@CompanyType = 2,
@WorkType =1,
@PageSize = 30,
@PageNumber =2000
SELECT 'Return Value' = @return_value
GO
SET STATISTICS IO OFF
// ----------------------------------------------- ------------------------
(30 row(s) affected)
Table 'Company'. Scan count 3, logical reads 632, physical reads 0
Table 'Position'. Scan count 3, logical reads 4865, physical reads 0
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0
// ----------------------------------------- ------------------------------
的執行計劃提示上(WorkExperience,WorkType缺失索引)。 但創建索引後(WorkExperience,WorkType)查詢速度較慢。
任何人給我的一些建議將非常感激。對不起,我的英語不好!
您能否提供關於節點「聚集索引掃描」的更多信息,其成本爲32%?以及成本19%的「密鑰查找」節點。 – yaoxing
可能的性能提升可能不是使用動態SQL。 – Alexander