如果我将冗长的SQL选择放入存储过程,是否会提高效率?

时间:2014-06-16 16:56:57

标签: sql-server sql-server-2012

我有以下SQL Server 2012查询:

var sql = @"Select question.QuestionUId
            FROM Objective,
                 ObjectiveDetail,
                   ObjectiveTopic,
                   Problem,
                   Question
            where objective.examId = 1
            and objective.objectiveId = objectiveDetail.objectiveId
            and objectiveDetail.ObjectiveDetailId = ObjectiveTopic.ObjectiveDetailId
            and objectiveTopic.SubTopicId = Problem.SubTopicId
            and problem.ProblemId = question.ProblemId";

            var a = db.Database.SqlQuery<string>(sql).ToList(); 

有人可以帮我解释一下,如果把它放进去是个好主意 存储过程如果是,那么我怎么能这样做然后从我的C#代码中调用它。它是 向我建议,如果它在存储过程中,那么它将运行更多 有效,因为它不会经常重新编译。是这样的吗?

1 个答案:

答案 0 :(得分:0)

是的,有。对于初学者,存储过程是预编译的并存储在数据库中。通过预编译,数据库引擎可以更有效地执行它,因为不需要动态编译。此外,可以添加数据库优化以支持预编译过程。存储过程还允许将业务逻辑封装在数据库中。

如果您决定使用存储过程路由,请考虑以下事项:

首先,您需要创建一个封装现有SQL查询的存储过程。

CREATE PROCEDURE ListQuestionIds
    @ExamId int
AS
BEGIN

    SELECT Question.QuestionUId
    FROM Objective
    INNER JOIN ObjectiveDetail
        ON ( Objective.objectiveId = ObjectiveDetail.objectiveId )
    INNER JOIN ObjectiveTopic
        ON ( ObjectiveDetail.ObjectiveDetailId = ObjectiveTopic.ObjectiveDetailId )
    INNER JOIN Problem
        ON ( ObjectiveTopic.SubTopicId = Problem.SubTopicId )
    INNER JOIN Question
        ON ( Problem.ProblemId = Question.ProblemId )
    WHERE Objective.examId = @ExamId;

END;

请确保您的过程(ObjectiveProblem等)调用的表具有所有相关的主键和索引,以提高查询性能。

接下来,您需要从C#代码中调用该存储过程。一种方法 - 但绝不是唯一的方法 - 是使用SqlConnection对象创建与数据库的连接,然后通过SqlCommand对象执行您的过程。

我建议您查看一些主题示例How to execute a stored procedure within C# program。但是这样的一个简单例子可能如下:

string connectionString = "your_connection_string";

using (var con = new SqlConnection(connectionString))
{
    using (var cmd = new SqlCommand("ListQuestionIds", con)) {

        cmd.CommandType = CommandType.StoredProcedure

        cmd.Parameters.Add(new SqlParameter("@ExamId", examId))

        con.Open();

        using (SqlDataReader rdr = cmd.ExecuteReader())
        {
            while (rdr.Read())
            {
                // Loop through the returned SqlDataReader object (aka. rdr) and
                // then evaluate & process the returned question id value(s) here
            }
        }
    }
}

请注意,此示例代码不会(故意)包含任何错误处理。我把它留给你,以便整合到你的应用程序中。

最后,就像一个FYI ......许多更现代的ORM(例如,Entity Framework,NHibernate等)允许您从C#代码执行类似存储过程的查询,而无需显式存储过程。如果您已在应用程序中使用ORM,那么您可能希望完全放弃存储过程。无论你决定做什么,对你的一些研究都会帮助你做出明智的决定。

我希望这有助于您入门。祝你好运。