Showing posts with label retrieve. Show all posts
Showing posts with label retrieve. Show all posts

Wednesday, March 28, 2012

Performance recommendation

Please give me some advice. In my application I calculate a list of identifiers (Guids) that are primary keys in my table and I have to retrieve those rows from the database. So my first approach is like

Code Snippet

SELECT id, c2 FROM t1 WHERE id IN (@.id1, @.id2, @.id3,....)

where @.idn are the calculated identifies as parameters. This approach does not scale well since there is a limit of parameters that can be used. So one possibility might be to use several SELECT statements, each with the maximum number of parameters. I can't believe that this is a good solution. A temporary table may be a better solution - I don't know. Are there any better ways to retrieve performantly - any recommandations?

Thanks a lot

Hans-Peter


Code Snippet

SELECT id, c2
FROM
t1 a
Join
(Select @.Id1 Index#
union all
Select @.Id2
union all
select @.Id3
...
...
union all
select @.Idn) as b
On
a.Id = b.Index#


|||

First, GUIDs as primary keys is not usually a good idea. See these articles for more information.

GUID -Identity and Primary Keys
http://sqlteam.com/item.asp?ItemID=2599

GUID -Is not Always GOOD
http://bloggingabout.net/blogs/wellink/archive/2004/03/15/598.aspx

GUID -The Cost of GUIDs as Primary Keys
http://www.informit.com/articles/article.asp?p=25862&rl=1

GUID -Uniqueidentifier vs. IDENTITY
http://sqlteam.com/item.asp?ItemID=283

Secondly, using a table variable could be useful.

|||

Arnie is correct that using GUID's for a Primary Key is not a good idea from a performance and maintenance point of view.

It is also a bad idea to use big IN clauses in the WHERE clause of a SELECT statement, since that will give you a large ad-hoc plan with a use count of 1 that will bloat your procedure cache. One work-around to avoid this is to add OPTION (RECOMPILE) to the end of your query, so SQL Server does not cache the plan (which won't be re-used anyway).

You can run this DMV to see if you are experiencing this problem:

Code Snippet

-- Find the ad-hoc queries that are bloating the plan cache

SELECT TOP(1000) *

FROM sys.dm_Exec_cached_plans

CROSS APPLY sys.dm_exec_sql_text(plan_handle)

WHERE cacheobjtype = 'Compiled Plan'

AND objtype = 'Adhoc' AND usecounts = 1

--AND size_in_bytes < 200000

ORDER BY size_in_bytes DESC

I recommend that you build a stored procedure that has say 20 or 50 input parameters, then have a SELECT statement that uses an OR for each parameter. Then call the SP as many times as you need to. You can just use duplicates if you have less than 20 or 50 values for a call.

Code Snippet

SELECT id, c2

FROM t1

WHERE id = @.id1

OR id = @.id2

OR id = @.id3....

|||

Thanks a lot for your recommendations! Let me explain my insight:

There are different ways to avoid the IN with many arguments. One way is that Bushan shows (select and union all parameters internally) and

one way to use ORs. I will try both ways to check performance improvement.

But I still have some questions:

Limits of parameters / command length|||

The best way to compare two alternative ways of doing it is to run the queries back to back in SSMS, with SET STATISTICS IO enabled, and the graphical execution plan turned on. Then you can compare the cost the batches, and you will be able see the percentage cost of each batch, and compare the IO cost also.

If you want to take caching out of it, you can run DBCC DROPCLEANBUFFERS and DBCC FREEPROCCACHE before each testing run, (but don't do that on a Production system).

Using a very big IN clause will really bloat your Procedure cache with single-use, ad-hoc query plans, which can really eat up some memory.

|||

Thanks for your advice, Glenn!

Hans-Peter

|||

Hi Hans-Peter,

are you building a DW or an OLTP system....

The usual case in DWs is to use generated integer keys all the time....

In OLTP using generated integer keys is often a good idea but it is by no means a hard and fast rule...

if you use integers like this then most queries are where clauses on attributes that link back to the integer...when you want to group things together and shorten where clauses you add attributes to group things.....

Best Regards

Tuesday, March 20, 2012

performance problem with linked sybase tables

We have a need to retrieve Sybase data within a MS SQL Server
application. We are using SQL Server's linked database feature with
the Sybase 12.0 OLE DB driver. It takes 5 minutes to run a query that
takes 2 seconds from isql.

Any suggestions?

ThanksLarryboy (dean.roberts@.sscgp.com) writes:
> We have a need to retrieve Sybase data within a MS SQL Server
> application. We are using SQL Server's linked database feature with
> the Sybase 12.0 OLE DB driver. It takes 5 minutes to run a query that
> takes 2 seconds from isql.

I guess you need to do some analysis to see whether it's
a network problem, or whether it could be that the query gets a different
query plan when it comes in on the linked server. If running sp_who
on the Sybase machine through the linked server is fast, then we can
rule out network.

I don't know about Sybase, but on MS SQL Server you can different
query plans depending on the SET options. I don't know if Sybase
has DBCC USEROPTIONS, but if it has, you can run this both in ISQL
and through the linked server, to see if there are any differences.

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp

Monday, March 12, 2012

Performance penalty for LIKE when I really mean Equal?

Hi,
I have a situation where I can retrieve either all the rows in a table or
just some of them based on a "type" field in the row. The type of the rows
to select is passed as a parm to the method that retrieves the rows. If the
calling program wants the whole table it passes String.Empty as the type.
I was thinking of having one parameterized SQL statement like this...
SELECT * FROM T1 WHERE T1.TYPE LIKE @.Type
I'll append '%' to whatever "type" is passed the method. So if the calling
routine wants all records, LIKE '%' should return all rows. If the User
passes 'OT' (assuming a two character type code) I should still get all the
'OT' rows from the passed parm of
'OT%'.
Will I suffer a performance penalty by doing this, or is the query optimizer
smart enough to figure out that for a two character field, LIKE 'OT%' is th
e
equivalent of = 'OT'?
Thanks.
BBMFor prefix criteria (i.e. where the wildcard character is not used at the
beginning of the search argument), the query optimizer can take advantage of
indexes if the column used in the LIKE expression is indexed.
ML|||If @.Type is NULL, then the following will return all rows without evaluating
the like comparison:
SELECT * FROM T1 WHERE (@.Type Is Null) or (T1.TYPE LIKE @.Type)
"BBM" <bbm@.bbmcompany.com> wrote in message
news:E8437BCA-E0D4-4D1D-9A98-5F62A95938BE@.microsoft.com...
> Hi,
> I have a situation where I can retrieve either all the rows in a table or
> just some of them based on a "type" field in the row. The type of the
> rows
> to select is passed as a parm to the method that retrieves the rows. If
> the
> calling program wants the whole table it passes String.Empty as the type.
> I was thinking of having one parameterized SQL statement like this...
> SELECT * FROM T1 WHERE T1.TYPE LIKE @.Type
> I'll append '%' to whatever "type" is passed the method. So if the
> calling
> routine wants all records, LIKE '%' should return all rows. If the User
> passes 'OT' (assuming a two character type code) I should still get all
> the
> 'OT' rows from the passed parm of
> 'OT%'.
> Will I suffer a performance penalty by doing this, or is the query
> optimizer
> smart enough to figure out that for a two character field, LIKE 'OT%' is
> the
> equivalent of = 'OT'?
> Thanks.
> BBM|||Thanks for the tip. I'll try this.
"JT" wrote:

> If @.Type is NULL, then the following will return all rows without evaluati
ng
> the like comparison:
> SELECT * FROM T1 WHERE (@.Type Is Null) or (T1.TYPE LIKE @.Type)
>
> "BBM" <bbm@.bbmcompany.com> wrote in message
> news:E8437BCA-E0D4-4D1D-9A98-5F62A95938BE@.microsoft.com...
>
>

Friday, March 9, 2012

Performance of XML EXPLICIT vs XML AUTO and XML transform

I need to retrieve data, as XML, from 8 tables that are related by a common
primary key. Ultimately the data should be in a format similar to:
<Table1 field1="blah">
<Table2 field1="blah"/>
<Table2 field1="blah"/>
<Table3 field1="blah"/>
<Table3 field1="blah"/>
<Table4 field1="blah"/>
<Table5 field1="blah"/>
<Table6 field1="blah"/>
<Table7/>
<Table8 field1="blah"/>
</Table1>
For a given successful query, some of the tables will have 1 or more
matching records, others will have 0 or more, and Table 1 will have 1
record. I am currently using joins and XML AUTO to retrieve the data, and
then passing it through an XSL transform to get it into the format I need.
An alternative would be to use a UNION and XML EXPLICT to accomplish the
same thing.
Since ultimately performance will be an issue, it there anyway, short of a
perormance test, to tell which method will be faster? Are there any other
ways to accomplish this that I should consider?
Thanks in advance
-Andy
"Andy Walldorff" <andyw@.REMOVEsuperior.net> wrote in message
news:eWJm5okoEHA.2784@.TK2MSFTNGP14.phx.gbl...
[snip]
> Since ultimately performance will be an issue, it there anyway, short of a
> perormance test, to tell which method will be faster? Are there any other
> ways to accomplish this that I should consider?
You will have to run a test since there are quite a few factors. I think the
XSL method is probably the fastest and it seems the cleanest.
http://www.sqlxml.org/faqs.aspx?faq=55
Bryant
|||"Bryant Likes" <bryant@.suespammers.org> wrote in message
news:%23sSRGlnoEHA.516@.TK2MSFTNGP09.phx.gbl...[vbcol=seagreen]
> "Andy Walldorff" <andyw@.REMOVEsuperior.net> wrote in message
> news:eWJm5okoEHA.2784@.TK2MSFTNGP14.phx.gbl...
> [snip]
a[vbcol=seagreen]
other
> You will have to run a test since there are quite a few factors. I think
the
> XSL method is probably the fastest and it seems the cleanest.
> http://www.sqlxml.org/faqs.aspx?faq=55
> --
> Bryant
>
Thanks