views:

341

answers:

7

Here's an argument for SPs that I haven't heard. Flamers, be gentle with the down tick,

Since there is overhead associated with each trip to the database server, I would suggest that a POSSIBLE reason for placing your SQL in SPs over embedded code is that you are more insulated to change without taking a performance hit.

For example. Let's say you need to perform Query A that returns a scalar integer.

Then, later, the requirements change and you decide that it the results of the scalar is > x that then, and only then, you need to perform another query. If you performed the first query in a SP, you could easily check the result of the first query and conditionally execute the 2nd SQL in the same SP.

How would you do this efficiently in embedded SQL w/o perform a separate query or an unnecessary query?

Here's an example:

--This SP may return 1 or two queries.

SELECT @CustCount = COUNT(*) FROM CUSTOMER

IF @CustCount > 10 SELECT * FROM PRODUCT

Can this/what is the best way to do this in embedded SQL?

A: 

How would you do this efficiently in embedded SQL w/o perform a separate query or an unnecessary query?

Depends on the database you are using. In SQL Server, this is a simple CASE statement.

RedFilter
How about an embedded SQL example, please? See the SQL snippet I added to the question.
Velika
Your snippet doesn't make sense as one query returns a scalar and the other a table. Shouldn't the second query return a scalar as well?
RedFilter
I don't understand why that distinction is relevant. Could you please explain?
Velika
Additional pt: Granted that the example given does not seem likely in real life, the intent was just to provide SQLs that could be used for conversation and couldbe modified by embedded-SQL proponents to show how this same result could be acheived in embedded SQL. If you would like a more realistic example, I will try to come up with one.
Velika
I am trying to reconcile your example with the Single Responsibility Principle (http://en.wikipedia.org/wiki/Single_responsibility_principle) - do you have an example where the resulting data type does not change? One query is giving a count, the other a recordset, two different purposes - not sure why you would want to encapsulate this in one operation.
RedFilter
I guess I intended the 1st query to return a scalar unconditionally. Let's say the scalar value is returned via an output param. Then, based on the result of the above scalar value, an OPTIONAL query may or may not be executed. In other words, it only made sense to look for the additional data of the 2nd SQL if the conditions of the first SQL were met. I think I see where you are going with the "single principle theory"-I'm thinking splitting up the proc into 2 procs may increase reusability but at the cost of performance. I think the Google's success is more due to speed than search results.
Velika
+1  A: 

I would generally never put business logic in SP's, I like them to be in my native language of choice outside the database. The only time I agree SPs are better is when there is a lot of data movement that don't need to come out of the db.

So to aswer your question, I'd rather have two queries in my code than embed that in a SP, in my view I am trading a small performance hit for something a lot more clear.

Otávio Décio
A: 

Perhaps include the WHERE clause in that sproc:

WHERE (all your regular conditions)
AND   myScalar > myThreshold
p.campbell
hmm. I don't want to change the first SQL's results. I want to conditionally execute the 2nd. Please see the edited original question which includes a small SQL example.
Velika
+3  A: 

A very persuasive article

SQL and stored procedures will be there for the duration of your data.

Client languages come and go, and you'll have to re-implement your embedded SQL every time.

gbn
I wish I could vote you more than once for this article. Compelling points that I haven't heard before.
Velika
SQL doesn't change whether it's embedded in another language or not. And anyway, you should be seeking minimize the custom SQL you write as much as possible.http://www.lostechies.com/blogs/chad_myers/archive/2008/02/21/sql-is-the-assembly-language-of-the-modern-world.aspx
chadmyers
@chadmyers: when you work on bigger systems, ORMs fail miserably. And they can't deal with properly designed databases because they dictate design to you. And it does not invalidate my answer because you still have to reimplement the ORM every time. A stored proc is a method
gbn
I've heard the fallacy of "when you work on bigger systems" - I've worked on bigger systems unless you're talking about Facebook big in which case RDBMS fails. ORM works as long as RDBMS works. If ORM fails, then generally you shouldn't be using an RDBMS in the first place. ORM is used for the CRUD side and isn't as useful for the querying/reporting side, though. In that case, SP's aren't much more useful and you need a different strategy (OLAP, denormalized store, etc) anyhow. The arguments FOR SP's are usually all based on fallacies and ignorance, IMHO
chadmyers
@chadmyers: we'll have to disagree then
gbn
A: 

Benefits of SPs:

  1. Performance (are precompiled)
  2. Easy to change (without compiling the application)
  3. SQL set based features make very easy doing really difficult data tasks

Drawbacks:

  1. Depend heavily on the database engine used
  2. Makes deployment of upgrades a little harder (you have to deploy the App + the scripts)

My 2 cents...

About your example, it can be done like this:

select * from products where (select count(*) from customers>10)
tekBlues
"Performance (are precompiled)" This was true with SQL Server 7, less so with Sql Server 2000, non existent with Sql Server 2005. 2008, I would beg to differ the opposite is true.
mxmissile
@mxmissile, interesting point, I will check it up, that's what I like about SO each day you learn a lot...
tekBlues
SQL Server 2005/2008 does execution plan caching for both sprocs and regular queries, treating them as essentially the same. "The main performance advantage that stored procedures and triggers have in SQL Server compared with batches of dynamic SQL is that their SQL statements are always the same." Sources [http://msdn.microsoft.com/en-us/library/ms190201.aspx] and [http://msdn.microsoft.com/en-us/library/ms181055.aspx] However, I'm not sure how you can say the opposite is true.
Dave Bauman
Yes, SQL Server 2005/2008 does execution plan caching for regular queries--but it will only reuse an existing plan if the "new" query matches the one on which the plan is based to a very high degree. I've seen where extra white space will cause a new compilation....
RolandTumble
ah! very good! I see the pt. I just don't like that the 2nd SQL is executed unconditionally but I realize that the optimizer may not re-execute the () inner SQL which was previously executed.
Velika
Performance isn't a big plus for SProcs anymore - SECURITY is. With SProcs, you can limit access for users to executing the SProcs - NO direct table access. This can be a HUGE plus in certain scenarios.
marc_s
+2  A: 

In the example you provide, the time saved is sending a single scalar value and a single follow-up query over the wire. This is insignificant in any reasonable scenario. That's not to say there might not be other valid performance reasons to use SPs; just that this isn't such a reason.

Carl Manaster
Is it always insignificant? I would think that if you are executing two separate SQLs from a web server to a database where the pipe between them is optimized, that this may be insignificant, but that these occurrences can multiply over time leaving you with a slow app, but what if you are dealing with a fat client?
Velika
I think it is always insignificant. If the trip time for a scalar and a query string is a significant chunk of your query execution cycle, your query is too small (like, you're doing a thousand equals queries instead of an IN query, or re-querying for each row in a result set, etc.) If you have a case where this represents a significant savings, there are other, bigger, problems with your system.
Carl Manaster
My perspective is that simply making a server hop to perform a query is expensive, regardless of the SQL that is performed. If you have a fat client, how would you expect the client talk to the db? Directly or through a web service of some type? If the latter, are we not talking about two hops? 1) from the fat client to the web server and 2) from the web server to the database? I find each hop (not counting query time) to be sub-second for the most part, but my general experience in our company is that the network is pretty slow, and still, the nwetwk infrastructure may chg anytime.
Velika
A: 

Lately I prefer to not use SPs (Except when uber complexity arises where a proc would just be better...or CLR would be better). I have been using the Repository pattern with LINQ to SQL where my query is written in my data layer in a strongly typed LINQ expression. The key here is that the query is strongly typed which means when I refactor I am refactoring properties of a class that is directly generated from the database table (which makes changes from the DB carried all the way forward super easy and accurate). While my SQL is generated for me and sent to the server I still have the option of sticking to DRY principles as the repository pattern allows me to break things down into their smallest component. I do have the issue that I might make a trip to the server and based on the results of query I may find that I need to make another trip to the server. I don't worry about this up front. If I find later that it becomes an issue then I may refactor that code into something more performant. The over all key here is that there is no one magic bullet. I tend to work on greenfield applications which allows this method of development to be most efficient for me.

Andrew Siemer
LINQ intrigues me, though aside from hello world examples, I haven't used it. To me, the strong binding part of it is very appealing. The appeal of LINQ, to me, may be enough to lead me away from SPs, but I am cautious about the idea that "if things become a problem later, they can be refactored."
Velika
If you have good separation of concerns (such as a repository pattern) your application have no knowledge of stored procedures, inline sql, LINQ to SQL, NHibernate, Entity Framework, XML, etc. The only issue I have when using LINQ to SQL or Entity Framework is that they do not use truley POCO type classes (though EF is closer). This is an acceptable tradeoff for me though as it cuts back on the amount of work I need to do. NHibernate offers this really well if you require it! This makes refactoring out a technology pretty straight forward. That and using StructureMap all over the place!
Andrew Siemer