介绍
我的一位朋友问:“在存储过程中创建索引更好吗?”虽然它取决于存储过程中使用的列来提高 Join 性能并在获得所需输出之后和结束之前删除存储过程......
技术解答
...是的,我们可以在存储过程中创建一个索引。
现在,我们必须思考我们的答案意味着什么
从技术上讲,我朋友在场景中提到的是可能的。但就性能而言,这又是一个有问题的解决方案。这意味着解决一些问题我们又制造了另一个问题。为了正确理解它,让我们举一个这种存储过程的例子。
IF OBJECT_ID(N'[dbo].[sproc_StudentDetails]', N'P')IS NOT NULL
DROP PROCEDURE [dbo].[sproc_StudentDetails];
GO
CREATE PROCEDURE [dbo].[sproc_StudentDetails]
(
@p_StdClass INT
)
AS
BEGIN
-- Creating Non Clustered Index on IDNO
CREATE NONCLUSTERED INDEX IX_NC_IDNO_StdDtl
ON tbl_StudentDetails(IDNO);
CREATE NONCLUSTERED INDEX IX_NC_IDNO_StdMarks
ON tbl_StudentMarks(IDNO);
-- Making JOIN on IDNO for Performance Reason
SELECT a.Roll, a.StdName, b.Marks1, b.Marks2
FROM tbl_StudentDetails AS a
INNER JOIN tbl_StudentMarks AS b ON a.IDNO = b.IDNO;
-- Droping the Index
DROP INDEX IX_NC_IDNO_StdDtl ON tbl_StudentDetails;
DROP INDEX IX_NC_IDNO_StdMarks ON tbl_StudentMarks;
END
GO
在此示例中,如果我们仔细查看,将创建无聚簇索引,并且在成功加入后再次删除。
它在技术上是完美的。
那么,问题是什么...
IF OBJECT_ID(N'[dbo].[sproc_StudentDetails]', N'P')IS NOT NULL
DROP PROCEDURE [dbo].[sproc_StudentDetails];
GO
CREATE PROCEDURE [dbo].[sproc_StudentDetails]
(
@p_StdClass INT
)
AS
BEGIN
-- Creating Non Clustered Index on IDNO
CREATE NONCLUSTERED INDEX IX_NC_IDNO_StdDtl
ON tbl_StudentDetails(IDNO);
CREATE NONCLUSTERED INDEX IX_NC_IDNO_StdMarks
ON tbl_StudentMarks(IDNO);
-- Making JOIN on IDNO for Performance Reason
SELECT a.Roll, a.StdName, b.Marks1, b.Marks2
FROM tbl_StudentDetails AS a
INNER JOIN tbl_StudentMarks AS b ON a.IDNO = b.IDNO;
-- Droping the Index
DROP INDEX IX_NC_IDNO_StdDtl ON tbl_StudentDetails;
DROP INDEX IX_NC_IDNO_StdMarks ON tbl_StudentMarks;
END
GO
由于非聚集索引,JOIN 条件的性能得到提高。所以我们认为我们获得了性能提升……但事实上,我们没有。在实施之前始终充分理解。
当Index创建Index表和Statistical表时,两者都会更新,所以在存储过程中再次创建索引需要很长时间才能创建。
通过创建索引,我们解决了 Join 性能问题,但是创建索引的时间又是一个痛点,它会降低存储过程的性能。
希望你喜欢。