473,385 Members | 1,873 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Should I worry

I have a stored procedure where I need to pass in a comma separated
list of symbols and return back results.

My original code built up the query (as a string) and used
sp_executesql to execute it. I took the comma separated list of symbols
and appended it to the query as part of the WHERE clause.

When viewing the execution plan, I noted that the query used the
indices I set on the tables (as I expected it would).

I now want to move away from the sp_executesql statement. My approach
is to follow what Erland says (on his website) and break out the comma
separated list to a temp table and JOIN that to my main query. Except
for the additional JOIN to the temp table, my new query looks just like
my old query.

But now when I look at the execution plan, almost NONE of lookups are
using indices but are doing table scans instead. (And I think it
actually runs a bit slower...)

Am I doing something wrong? Is using sp_executesql a better way to go?
If SQL is not using my indices, should I trust it or be worried that I
am not getting the best performance that I could be?

I am posting the queries for review but no code for recreating tables
since this is more of an opinion question.

Old Query
----------------------------------------------
CREATE PROCEDURE spFetchIndexComponentsBySymbol (
@indexSymbols VARCHAR(2000) = NULL
)
AS
SET NOCOUNT ON

DECLARE @sql NVARCHAR(4000)

-- build base SQL statement
SELECT @sql =
'SELECT
IC.[IndexSymbol],
IC.[IndexIdentity],
IC.[Symbol],
IC.[Identity],
SM.[Name],
SME.[Exchange],
IC.[Shares]
, BBO.[Last] AS [ClosingPrice]
FROM
Trading.dbo.IndexComponent IC
JOIN
Trading.dbo.SecurityMaster SM
ON
SM.[Symbol] = IC.[Symbol]
AND SM.[Identity] = IC.[Identity]
LEFT JOIN
Trading.dbo.SM_mm_Exchange SME
ON
SME.[Symbol] = IC.[Symbol]
AND SME.[Identity] = IC.[Identity]
AND SME.[PrimaryExchangeFlag] = 1
LEFT JOIN
[Trading].[dbo].[BestBidOffer] BBO
ON
BBO.[Symbol] = IC.[Symbol]
AND BBO.[Identity] = IC.[Identity]
WHERE
1 = 1'

-- process symbol parameter
IF @indexSymbols IS NOT NULL
SELECT @sql = @sql + ' AND [IndexSymbol] IN (' + @indexSymbols + ')'

-- execute it
EXEC sp_executesql @sql
GO

New Query
--------------------------------------------------------------------
CREATE PROCEDURE spFetchIndexComponentsBySymbol (
@indexSymbols VARCHAR(2000) = NULL
)
AS
SET NOCOUNT ON

-- perform query
SELECT
IC.[IndexSymbol]
, IC.[IndexIdentity]
, IC.[Symbol]
, IC.[Identity]
, SM.[Name]
, SME.[Exchange]
, IC.[Shares]
, BBO.[Last] AS [ClosingPrice]
FROM
[Trading].[dbo].[IndexComponent] IC
JOIN
[Trading].[dbo].[SecurityMaster] SM
ON
SM.[Symbol] = IC.[Symbol]
AND SM.[Identity] = IC.[Identity]
LEFT JOIN
[Trading].[dbo].[SM_mm_Exchange] SME
ON
SME.[Symbol] = IC.[Symbol]
AND SME.[Identity] = IC.[Identity]
AND SME.[PrimaryExchangeFlag] = 1
LEFT JOIN
[Trading].[dbo].[BestBidOffer] BBO
ON
BBO.[Symbol] = IC.[Symbol]
AND BBO.[Identity] = IC.[Identity]
-- Join against temp table to expand comma separated list of symbols
LEFT JOIN
[Supporting].[dbo].[fDelimetedStringToTable](@indexSymbols, DEFAULT)
ST
ON
ST.[Value] = IC.[Symbol]
WHERE
-- check if symbol was one of those specified
(NOT ST.[Value] IS NULL OR @indexSymbols IS NULL)
GO

Dec 6 '05 #1
3 1145
(Ja*******@hotmail.com) writes:
My original code built up the query (as a string) and used
sp_executesql to execute it. I took the comma separated list of symbols
and appended it to the query as part of the WHERE clause.

When viewing the execution plan, I noted that the query used the
indices I set on the tables (as I expected it would).

I now want to move away from the sp_executesql statement. My approach
is to follow what Erland says (on his website) and break out the comma
separated list to a temp table and JOIN that to my main query. Except
for the additional JOIN to the temp table, my new query looks just like
my old query.

But now when I look at the execution plan, almost NONE of lookups are
using indices but are doing table scans instead. (And I think it
actually runs a bit slower...)


It is true that with dynamic SQL, the optimizer has more information
about what rows that are affected. A table-valued function is opaque to the
optimizer; it has no idea what is in it. This can be cirumvented by
getting the data from the list into a temp table (not a table variable),
as a temp table has statistics.

But you problem is another:

LEFT JOIN
[Supporting].[dbo].[fDelimetedStringToTable](@indexSymbols,
DEFAULT)
ST
ON
ST.[Value] = IC.[Symbol]
WHERE
-- check if symbol was one of those specified
(NOT ST.[Value] IS NULL OR @indexSymbols IS NULL)

Since you left-join with the table-function, you are including all
rows from IndexComponent, and the function cannot be used for selecting
at all. You would have to have to different queries, one with the
list and one without it.

--
Erland Sommarskog, SQL Server MVP, es****@sommarskog.se

Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pro...ads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinf...ons/books.mspx
Dec 6 '05 #2
Thanks for the reply Erland.

As you can see, I did the left-join so the user can pass null and get
everything or they can ask for specific symbols.

As to having different queries, what is the communities opinion about
having two queries in the same stored procedure and using an IF
statement to branch to one of them? Does that play havoc with the
execution plan since either query can be called? (I could create
another stored procedure to handle ALL securities but I already have
applications out there that use my existing one.)

Dec 6 '05 #3
(Ja*******@hotmail.com) writes:
As you can see, I did the left-join so the user can pass null and get
everything or they can ask for specific symbols.

As to having different queries, what is the communities opinion about
having two queries in the same stored procedure and using an IF
statement to branch to one of them? Does that play havoc with the
execution plan since either query can be called? (I could create
another stored procedure to handle ALL securities but I already have
applications out there that use my existing one.)


There is a risk at some occassions due to parameter sniffing. If you have
say:

IF @x IS NOT NULL
SELECT ... FROM tbl WHERE x = @x
ELSE IF @y IS NOT NULL
SELECT ... FROM tbl WHERE y = @y

Say that first time the procedure is called with a value @x in. The plan
will then be built with the assumption that @y is NULL, which may not be
the best.

One way to handle this, is to have sub-procedures for each query.
Admittedly, this is not very manageable. Another way is to use dynamic
SQL, and I have an article on my web site about this:
http://www.sommarskog.se/dyn-search.html.

In this particular case, I don't think there is any reason for concern
though, as the optimizer is not likely to be able to make anything useful
from the parameter with the list.
--
Erland Sommarskog, SQL Server MVP, es****@sommarskog.se

Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pro...ads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinf...ons/books.mspx
Dec 7 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

29
by: Tom_OM | last post by:
I have a web site in which I offer freeware programs. They're true freeware, not crippled versions attempting to get people to buy the full versions. The beginning of my user license agreement...
303
by: mike420 | last post by:
In the context of LATEX, some Pythonista asked what the big successes of Lisp were. I think there were at least three *big* successes. a. orbitz.com web site uses Lisp for algorithms, etc. b....
16
by: Paul Prescod | last post by:
I skimmed the tutorial and something alarmed me. "Strings are a powerful data type in Prothon. Unlike many languages, they can be of unlimited size (constrained only by memory size) and can hold...
5
by: larry | last post by:
Hi. Our company has about 20 application developers/architects and one certified dba. Our developers both design the databases and build the applications. We're confused about what permissions a...
9
by: Weekend | last post by:
Currently, i want to develope a multiple choice exam website. The content of the test is store in an XML file. I want to carry out some function. Could you tell me which programming language should...
8
by: Chris Mayers | last post by:
I am trying to track a suspected memory leak in an application I'm writing and through repeated simplification of my project, I have found the following which is quite easily replicated should you...
5
by: elzacho | last post by:
I would like to (and commonly do) define my variables in the most specific scope I can. For example... int foo(int a, int b, int c) { /* don't declare temp here if we can help it */ ... ...
2
by: ABC | last post by:
How should I to release the pop-up page object on memory when I close the page? I have main page, which will open a popup webpage when a button clicked. In the first opened pop-up page, it is...
0
by: 88059355 | last post by:
Let go of outdated belief systems,There are SIMPLE and EFFECTIVE Tools to Deal with Worry! I know most of you already know that worry is useless. Worry takes us out of the present moment, where...
13
by: Ramon F Herrera | last post by:
I am writing a program that generates source code. See a snippet below. My question is about the use of that growing 'code' variable. Is it efficient? Is is recommended for this case? The code...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.