Firebird SQL Development
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me

The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.

Go Back   Dev Shed ForumsDatabasesFirebird SQL Development

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old November 24th, 2010, 04:38 AM
googlesteve googlesteve is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Oct 2010
Posts: 7 googlesteve User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 15 m
Reputation Power: 0
Paramitised queries prevent use of index

I have this SQL statement;

SELECT
QUOTES.QUOTE_REF,
SPARES.CODE,
QUOTE_LINES.QTY,
QUOTES.QUOTED,
QUOTES.QUOTE_ID
FROM
SPARES
INNER JOIN QUOTE_LINES ON QUOTE_LINES.SPARES_REF = SPARES.REF
INNER JOIN QUOTES ON QUOTES.REF = QUOTE_LINES.QUOTE_REF
WHERE
SPARES.CODE like 'FAN 010%'
ORDER BY
QUOTES.QUOTED DESC

It runs fast and uses this query plan;

PLAN SORT (JOIN (SPARES INDEX (RDB$34),QUOTE_LINES INDEX (I_QUOTE_LINES_SPARES_REF),QUOTES INDEX (PK_QUOTES)))

However, in my delphi application i would like to replace the criteria in the WHERE clause for a parameter. It is my understanding that it is good practice to use parameters because they protect against SQL injection and you can also utilise prepared queries.

So i changed the SQL statement to;

SELECT
QUOTES.QUOTE_REF,
SPARES.CODE,
QUOTE_LINES.QTY,
QUOTES.QUOTED,
QUOTES.QUOTE_ID
FROM
SPARES
INNER JOIN QUOTE_LINES ON QUOTE_LINES.SPARES_REF = SPARES.REF
INNER JOIN QUOTES ON QUOTES.REF = QUOTE_LINES.QUOTE_REF
WHERE
SPARES.CODE like :CODE
ORDER BY
QUOTES.QUOTED DESC

however, now the query runs really slow because it no longer uses the same query plan. The query plan it sugests is;

PLAN SORT (JOIN (QUOTES NATURAL,QUOTE_LINES INDEX (I_QUOTE_LINES_QUOTE_REF),SPARES INDEX (RDB$33)))

Why is it now using a NATURAL search on the QUOTES table?

If i sugest the original query plan it states that RDB$34 cannot be used in this query plan.

help!!!!!!!!!!!

Reply With Quote
  #2  
Old November 24th, 2010, 05:10 PM
clivew clivew is offline
Contributing User
Dev Shed Regular (2000 - 2499 posts)
 
Join Date: Jan 2006
Location: Carlsbad, CA
Posts: 2,045 clivew User rank is Major (30000 - 40000 Reputation Level)clivew User rank is Major (30000 - 40000 Reputation Level)clivew User rank is Major (30000 - 40000 Reputation Level)clivew User rank is Major (30000 - 40000 Reputation Level)clivew User rank is Major (30000 - 40000 Reputation Level)clivew User rank is Major (30000 - 40000 Reputation Level)clivew User rank is Major (30000 - 40000 Reputation Level)clivew User rank is Major (30000 - 40000 Reputation Level)clivew User rank is Major (30000 - 40000 Reputation Level)clivew User rank is Major (30000 - 40000 Reputation Level) 
Time spent in forums: 1 Week 6 Days 2 h 37 m
Reputation Power: 382
Quote:
WHERE
SPARES.CODE like 'FAN 010%'

If you use like, Firebird has no way of knowing whether you will pass in a value that can use the index.

Watch what happens to your plan if you use this where clause instead:
Code:
WHERE
SPARES.CODE like '%FAN 010%' 


Clive

Reply With Quote
  #3  
Old November 25th, 2010, 05:21 AM
googlesteve googlesteve is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Oct 2010
Posts: 7 googlesteve User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 15 m
Reputation Power: 0
Smile

Yes, it's making a bit more sense now.

The odd thing is, i'm not using the LIKE operator on the QUOTES table. I am in fact using it on the SPARES table.

I have since changed my program to use a stored procedure instead;

for SELECT
QUOTE_REF,
SPARES.CODE,
QUOTE_LINES.QTY
FROM
SPARES
INNER JOIN QUOTE_LINES ON QUOTE_LINES.SPARES_REF = SPARES.REF
WHERE
SPARES.CODE starting with :SE_CODE
PLAN JOIN (SPARES INDEX (I_SPARES_CODE,RDB$34),QUOTE_LINES INDEX (I_QUOTE_LINES_SPARES_REF))
into
:iQuoteRef,
:CODE,
:QTY
do begin
...

I have refrained from using STARTING WITH in the past because it restricts the user from entering wild cards at the begining of the search criteria. But thinking about it, if i use a wildcard at the begining of the search string, then any index would be useless anyway and a NATURAL search would have to be performed. However on large tables with serveral hundreds of thousands of records this is really slow. But i guess the is no solution.

Anyway, thanks.

Reply With Quote
  #4  
Old November 25th, 2010, 12:35 PM
clivew clivew is offline
Contributing User
Dev Shed Regular (2000 - 2499 posts)
 
Join Date: Jan 2006
Location: Carlsbad, CA
Posts: 2,045 clivew User rank is Major (30000 - 40000 Reputation Level)clivew User rank is Major (30000 - 40000 Reputation Level)clivew User rank is Major (30000 - 40000 Reputation Level)clivew User rank is Major (30000 - 40000 Reputation Level)clivew User rank is Major (30000 - 40000 Reputation Level)clivew User rank is Major (30000 - 40000 Reputation Level)clivew User rank is Major (30000 - 40000 Reputation Level)clivew User rank is Major (30000 - 40000 Reputation Level)clivew User rank is Major (30000 - 40000 Reputation Level)clivew User rank is Major (30000 - 40000 Reputation Level) 
Time spent in forums: 1 Week 6 Days 2 h 37 m
Reputation Power: 382
Quote:
I have refrained from using STARTING WITH in the past because it restricts.......
But i guess the is no solution.


Perhaps you are restricting the universe of solutions in which you are searching

I do not know enough about your application to understand what is possible but the following
options spring to mind immediately:

1. Offer the user two options, one that uses STARTING WITH one LIKE; wrapped, of course, in appropriate end user instructions and explanations.

2. Consider expanding the schema with some field that is a sub-string of the main field that can always use an index. This may fail Normalization rules but pass practical performance scrutiny. Alternatively, some category field(??) like 'FANS'.

In other words, look beyond simply crafting the SQL to achieve your goal.

Clive

Reply With Quote
Reply

Viewing: Dev Shed ForumsDatabasesFirebird SQL Development > Paramitised queries prevent use of index

Developer Shed Advertisers and Affiliates



Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.

© 2003-2013 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap