ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » SELECT FROM DynRefVar

Post new topic  Reply to topic Goto page 1, 2  Next
 SELECT FROM DynRefVar « View previous topic :: View next topic » 
Author Message
longng
PostPosted: Mon Mar 11, 2013 6:55 pm    Post subject: SELECT FROM DynRefVar Reply with quote

Apprentice

Joined: 22 Feb 2013
Posts: 42

I am a bit green on the nuance of SELECT statement (non-database) here and just wonder if anyone would comment.

I (may be incorrectly) assume that a dynamic reference variable can be used anywhere but then....

The code populates Environment.Variables.CustomerRequest.CorrelationId with array of Id's (for the sake of simplicity, assuming that the array has 5 elements Environment.Variables.CustomerRequest.CorrelationId.Id[5] and all fully populated, and
then:

A classic way that works

Code:

      SET rowId = THE(SELECT A.Id
      FROM Environment.Variables.CustomerRequest.CorrelationId[] AS A
      WHERE A.Id = CorrId);


Now I replace the above classic code as to use dynamic reference variables (supposed to be more efficient)
Code:

      DECLARE xxx REFERENCE TO Environment.Variables.CustomerRequest.CorrelationId;

      SET rowId = THE(SELECT A.Id
      FROM xxx AS A
      WHERE A.Id = CorrId);


The smart alex's code above appears to work but deeper analysis reveals a different story. The xxx variable always points to the same first element under CorrelationId and inside the SELECT statement, it seems to be aware of only that first element despite there are many more after that and the trace does confirm that's the case. i.e. something to the effect of "Finding one and only SELECT result. "

Can dynamic reference variable be used as FROM inside a SELECT statement? If yes, what's wrong with the above?
Back to top
View user's profile Send private message
marko.pitkanen
PostPosted: Mon Mar 11, 2013 11:22 pm    Post subject: Reply with quote

Chevalier

Joined: 23 Jul 2008
Posts: 440
Location: Jamsa, Finland

Hi,

You should consider what is difference between following quotes and what is their implication for your SELECT statements.

Quote:
An index clause can also consist of an empty pair of brackets ( [] ). This selects all fields with matching names.


Quote:
The REFERENCE data type holds the location of a field in a message.


--
Marko
Back to top
View user's profile Send private message Visit poster's website
Esa
PostPosted: Tue Mar 12, 2013 12:43 am    Post subject: Reply with quote

Grand Master

Joined: 22 May 2008
Posts: 1387
Location: Finland

In other words:

Make the reference xxx point to Environment.Variables.CustomerRequest and then select from xxx.CorrelationId[].

But in fact changing an ESQL select like yours to use a reference variable instead of a direct reference does not make it more efficient - it was already as efficient it can be.
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Tue Mar 12, 2013 3:00 am    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20756
Location: LI,NY

You want a result set instead of a single value. Have you looked up the significance of the "THE" statement in your ESQL?
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
Esa
PostPosted: Tue Mar 12, 2013 3:09 am    Post subject: Reply with quote

Grand Master

Joined: 22 May 2008
Posts: 1387
Location: Finland

fjb_saper wrote:
You want a result set instead of a single value. Have you looked up the significance of the "THE" statement in your ESQL?


No, he is assigining a singular value. The problem is that he gets a result only when the first id happens to match....
Back to top
View user's profile Send private message
mqjeff
PostPosted: Tue Mar 12, 2013 3:56 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

Esa wrote:
fjb_saper wrote:
You want a result set instead of a single value. Have you looked up the significance of the "THE" statement in your ESQL?


No, he is assigining a singular value. The problem is that he gets a result only when the first id happens to match....


The difference here is that in one case, the value being selected from is the entire set of children Environment.Variables.CustomerRequest.CorrelationId[] and in the second case it is the first child Environment.Variables.CustomerRequest.CorrelationId.

This is what marko.pitkanen has pointed out.
Back to top
View user's profile Send private message
longng
PostPosted: Tue Mar 12, 2013 7:24 am    Post subject: Reply with quote

Apprentice

Joined: 22 Feb 2013
Posts: 42

Esa wrote:
fjb_saper wrote:
You want a result set instead of a single value. Have you looked up the significance of the "THE" statement in your ESQL?


No, he is assigining a singular value. The problem is that he gets a result only when the first id happens to match....

@Esa: You're spot on!

My intention here is to find out if a correlation ID has already been inserted into the array, hence I purposely use the THE.

To explain further, I would like to explore a way to optimise the search for a particular correlation ID within the array and if it's not already there then it will be inserted into it. The array can potentially have hundreds of element and I find out that the performance of the searches and inserts is not that great since there are going to be as many searches as there are the number of elements within the array. That's why I try to wring out every last bit of performance by using the tripple X's dynamic variable

The general consensus on this board so far seems to indicate that the only correct way is to use a variable[] as a parameter for FROM and not the dynamic reference variable directly.

Is there a better algorithm?
Back to top
View user's profile Send private message
Esa
PostPosted: Tue Mar 12, 2013 7:50 am    Post subject: Reply with quote

Grand Master

Joined: 22 May 2008
Posts: 1387
Location: Finland

longng wrote:

Is there a better algorithm?


OK, if you are going to issue the search for hundreds of times within one flow instance, then you may win some nanoseconds or even milliseconds by using the reference variable. Just do not select from the reference itself, but from the array beneath it, as we all have been trying to explain...

What would you say about something like this:

Code:
DECLARE xxx REFERENCE TO Environment.Variables.CustomerRequest.CorrelationId;

....

IF NOT EXISTS(xxx.{CorrId}[]) THEN
  SET xxx,{CorrId} = CorrId;
ELSE
 -- you have a match!
END IF;


Didn't test this, but it might even work and give better performance. Depending on what you are trying to do with the list of correlation id's and the matching id's...
Back to top
View user's profile Send private message
Esa
PostPosted: Tue Mar 12, 2013 8:02 am    Post subject: Reply with quote

Grand Master

Joined: 22 May 2008
Posts: 1387
Location: Finland

By the way, you are obviously looping with MQGet. Unless you know how to do it properly - which I doubt - the cause of your performance problems is probably not the way you search but the way you loop...
Back to top
View user's profile Send private message
kimbert
PostPosted: Tue Mar 12, 2013 8:04 am    Post subject: Reply with quote

Jedi Council

Joined: 29 Jul 2003
Posts: 5542
Location: Southampton

Quote:
if you are going to issue the search for hundreds of times within one flow instance, then
...choose your data structure carefully!

If you have not already done so, I would consider one of the following:
- maintain a sorted array, and use a binary search
- store the values in a map
Those are probably best done using Java, which has excellent support for maps and arrays.
Back to top
View user's profile Send private message
rekarm01
PostPosted: Tue Mar 12, 2013 8:17 am    Post subject: Re: SELECT FROM DynRefVar Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 1415

longng wrote:
Now I replace the above classic code as to use dynamic reference variables (supposed to be more efficient)

Reference variables are only more efficient if they reduce the amount of tree navigation that a message flow needs to do to resolve references, and it's only significant if the message flow spends a lot of time navigating through trees. Using a reference variable only once per declaration is not more efficient, but using it to loop through the elements of an array can be.
Back to top
View user's profile Send private message
longng
PostPosted: Tue Mar 12, 2013 8:51 am    Post subject: Re: SELECT FROM DynRefVar Reply with quote

Apprentice

Joined: 22 Feb 2013
Posts: 42

rekarm01 wrote:
longng wrote:
Now I replace the above classic code as to use dynamic reference variables (supposed to be more efficient)

Reference variables are only more efficient if they reduce the amount of tree navigation that a message flow needs to do to resolve references, and it's only significant if the message flow spends a lot of time navigating through trees. Using a reference variable only once per declaration is not more efficient, but using it to loop through the elements of an array can be.


We don't have any disagreements there as that has been my intention to reduce tree traversals. In trying to do so, I/we now realize that it's not appropriate to use a dynamic reference variable directly for the FROM option in a SELECT statement.

Quote:

What would you say about something like this:

Code:

DECLARE xxx REFERENCE TO Environment.Variables.CustomerRequest.CorrelationId;

....

IF NOT EXISTS(xxx.{CorrId}[]) THEN
  SET xxx,{CorrId} = CorrId;
ELSE
 -- you have a match!
END IF;


Didn't test this, but it might even work and give better performance. Depending on what you are trying to do with the list of correlation id's and the matching id's...


Thanks Esa, that's a very interesting technique, I'll give it a try and share with you the results later.
Back to top
View user's profile Send private message
mqjeff
PostPosted: Tue Mar 12, 2013 9:32 am    Post subject: Re: SELECT FROM DynRefVar Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

longng wrote:
rekarm01 wrote:
longng wrote:
Now I replace the above classic code as to use dynamic reference variables (supposed to be more efficient)

Reference variables are only more efficient if they reduce the amount of tree navigation that a message flow needs to do to resolve references, and it's only significant if the message flow spends a lot of time navigating through trees. Using a reference variable only once per declaration is not more efficient, but using it to loop through the elements of an array can be.


We don't have any disagreements there as that has been my intention to reduce tree traversals. In trying to do so, I/we now realize that it's not appropriate to use a dynamic reference variable directly for the FROM option in a SELECT statement.


It's perfectly valid, and it's a somewhat reasonable performance enhancement. It reduces the tree navigation that the SELECT itself needs to process, potentially.

Again, the big difference between your two original statements is what you are selecting FROM. You provide a LIST of CorrelIDs in the first, working case, by using []. You provide a SINGLE CorrelID in the second, by pointing your reference at the FIRST child named CorrelID.

if you
Code:

      DECLARE xxx REFERENCE TO Environment.Variables.CustomerRequest;

      SET rowId = THE(SELECT A.Id
      FROM xxx.CorrelationId[] AS A
      WHERE A.Id = CorrId);


Then you should be good.
Back to top
View user's profile Send private message
longng
PostPosted: Tue Mar 12, 2013 11:27 am    Post subject: Re: SELECT FROM DynRefVar Reply with quote

Apprentice

Joined: 22 Feb 2013
Posts: 42

mqjeff wrote:
longng wrote:
rekarm01 wrote:
longng wrote:
Now I replace the above classic code as to use dynamic reference variables (supposed to be more efficient)

Reference variables are only more efficient if they reduce the amount of tree navigation that a message flow needs to do to resolve references, and it's only significant if the message flow spends a lot of time navigating through trees. Using a reference variable only once per declaration is not more efficient, but using it to loop through the elements of an array can be.


We don't have any disagreements there as that has been my intention to reduce tree traversals. In trying to do so, I/we now realize that it's not appropriate to use a dynamic reference variable directly for the FROM option in a SELECT statement.


It's perfectly valid, and it's a somewhat reasonable performance enhancement. It reduces the tree navigation that the SELECT itself needs to process, potentially.

Again, the big difference between your two original statements is what you are selecting FROM. You provide a LIST of CorrelIDs in the first, working case, by using []. You provide a SINGLE CorrelID in the second, by pointing your reference at the FIRST child named CorrelID.

if you
Code:

      DECLARE xxx REFERENCE TO Environment.Variables.CustomerRequest;

      SET rowId = THE(SELECT A.Id
      FROM xxx.CorrelationId[] AS A
      WHERE A.Id = CorrId);


Then you should be good.


Indeed! I do get a bit better performance with using a reference variable to refer to the nearest branch as noted by you.

I also try the approach posted by Esa

Code:

DECLARE xxx REFERENCE TO Environment.Variables.CustomerRequest.CorrelationId;

....

IF NOT EXISTS(xxx.{CorrId}[]) THEN
  SET xxx,{CorrId} = CorrId;
ELSE
 -- you have a match!
END IF;


but it does not seem to work for me as the test always returns negative (NOT EXISTS)...
Back to top
View user's profile Send private message
marko.pitkanen
PostPosted: Tue Mar 12, 2013 12:44 pm    Post subject: Reply with quote

Chevalier

Joined: 23 Jul 2008
Posts: 440
Location: Jamsa, Finland

Hi,

If I got it right you need to create fields named by the values you need to search to get Esa's code snippet working?

You could also try to build your own search / add routine with named loop over reference variable, move and leave statements. Then you perhaps can stop loop if you find the value from your list.

--
Marko
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic  Reply to topic Goto page 1, 2  Next Page 1 of 2

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » SELECT FROM DynRefVar
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.