While I agree with the comment of trying to get the page to be populated by a single query is the way to go. If you consider that 7*21 is 147 hits to the database for one page, each with its own different query is very expensive. Having one query could reduce the interactions with the database to a fraction of 147.
Your query has a UNION which can be expensive and a LIKE operator which is not easily index.
Lets start with an idea to remove the UNION. Within the UNION, the upper SELECT statement and lower SELECT statement share criteria and column list is very similar.
Here are the common criteria/predicates between the upper and lower SELECTs.
–where ap.appodate = ‘2006-01-31’
–and ap.matrix_agenda like ‘%|09:00|%’
–and ap.roomid = 15
–and i.categoriesid = ap.tipologid
Leaving only the following predicates as different.
and ap.anagid = 0 – not really sure what this means but I will defer
and ap.anagid = an.anagid – use to join the customers and appointments table
There is an IF expression with SQL Anywhere that may be helpful to accomodate the special anagid=0 case. The following query may be a format that gets your results without the need for a UNION.
select ap.appoid, if ap.anagid=0 then NULL else an.lastname endif as lastname, ap.apponotes, i.esacolor, ap.anagid
from appointments ap, customers an, categories i
where ap.appodate = ‘2006-01-31’
and ap.matrix_agenda like ‘%|09:00|%’
and (ap.anagid = an.anagid or ap.anagid=0)
and ap.roomid = 15
and i.categoriesid = ap.tipologid
To remove the LIKE clause, you can look at the nature of the data. It is a date manipulation that you are working with. The HOUR function may help you here. For example, HOUR(ap.matrix_agenda)=9 and to accomodate half hour segments MINUTE( ap.matrix_agenda) <30.
So your query could look like the following:
select ap.appoid, if ap.anagid=0 then NULL else an.lastname endif as lastname, ap.apponotes, i.esacolor, ap.anagid
from appointments ap, customers an, categories i
where ap.appodate = ‘2006-01-31’
–and ap.matrix_agenda like ‘%|09:00|%’
and (MINUTE( ap.matrix_agenda) <30 and HOUR(ap.matrix_agenda)=9 )
and (ap.anagid = an.anagid or ap.anagid=0)
and ap.roomid = 15
and i.categoriesid = ap.tipologid
SQL Anywhere can index functions which may prove useful to enable indexed lookups with this functions. See the CREATE INDEX statement on details on this.
My suggestions may be way off, if I am misinterpreting the meaning. Please test and verify the results.
Chris Gruber
iAnywhere Solutions
PS - Just as an idea for a query that could service most your data requirements for the page could be as follows:
select ap.appoid, if ap.anagid=0 then NULL else an.lastname endif as lastname, ap.apponotes, i.esacolor, ap.anagid , (HOUR(ap.matrix_agenda) || if MINUTE( ap.matrix_agenda)<30 then ‘:00’ else ‘:30’ endif) as timesegment
from appointments ap, customers an, categories i
where ap.appodate = ‘2006-01-31’
–and ap.matrix_agenda like ‘%|09:00|%’
–and (MINUTE( ap.matrix_agenda) <30 and HOUR(ap.matrix_agenda)=9 )
and (ap.anagid = an.anagid or ap.anagid=0)
–and ap.roomid = 15
and i.categoriesid = ap.tipologid
order by roomid,timesegment,ap.appoid