Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re: s/Perl/SQL/ ?

by roboticus (Chancellor)
on Sep 10, 2012 at 14:22 UTC ( [id://992770]=note: print w/replies, xml ) Need Help??


in reply to s/Perl/SQL/ ?

Freezer:

A join might be helpful, as you're guessing. Considering that it's using the same conditionals and tables, it would likely be good to refactor the SQL a bit. On first glance, it looks like you're using extremely similar conditions, so you could perhaps change it to:

SELECT '".$Reference."', '".$Comparitor."', A.entity_name FROM e_annotation_090812.annotation A join e_annotation_090812.Temp_table T on T.Line=A.user where A.entity_name like '_%' and A.evidence_code not like '%_________8__' and (A.centre like '".$Reference."' or A.centre like '".$Comparitor. +"')

I don't use mysql, but if it's like Oracle, then the "_" is a wildcard character, so effectively the first like expression is merely checking that the string is at least one character long, and the second checks that the string is at least 12 characters long with an 8 as the third-from-last character. The final like clauses could easily be converted to simple comparisons. So you could possibly gain a bit of speed (be sure to benchmark it!) by just doing the explicit checks:

SELECT '".$Reference."', '".$Comparitor."', A.entity_name FROM e_annotation_090812.annotation A join e_annotation_090812.Temp_table T on T.Line=A.user where length(A.entity_name)>0 and ( length(A.evidence_code)<12 or substring(A.evidence_code,length(A.evidence_code)-2,1)<>'8') ) and (A.centre = '".$Reference."' or A.centre = '".$Comparitor."')

Finally, to get rid of the trivial amount of embedded perl, you could use placeholders:

my $ST = $DB->prepare(<<EOSQL); SELECT ?, ?, A.entity_name FROM e_annotation_090812.annotation A join e_annotation_090812.Temp_table T on T.Line=A.user where length(A.entity_name)>0 and ( length(A.evidence_code)<12 or substring(A.evidence_code,length(A.evidence_code)-2,1)<>'8') ) and (A.centre=? or A.centre=?) EOSQL $ST->execute($Reference, $Comparitor, ".$Reference.", ".$Comparitor.") +;

Update: Changed != to <> and substr to substring Re^4: s/Perl/SQL/ ? as described by Anonymous Monk. I didn't *fully* fix substring, as I've never seen nor tried the form "substring(A.foo from 1 for 2)". I don't doubt that it's correct (I even double-checked the SQL92 and SQL2002 docs referenced at http://savage.net.au/SQL/.) It's just too ugly for me to consider. ;^)

...roboticus

When your only tool is a hammer, all problems look like your thumb.

Replies are listed 'Best First'.
Re^2: s/Perl/SQL/ ?
by Freezer (Sexton) on Sep 10, 2012 at 14:37 UTC
    This bit of code (update: shown above) looks very interesting. Can anyone convert the SQL easily into MySQL speak? Am I right in thinking that the syntax shown is Oracle?
    my $ST = $DB->prepare(<<EOSQL); SELECT ?, ?, A.entity_name FROM e_annotation_090812.annotation A join e_annotation_090812.Temp_table T on T.Line=A.user where length(A.entity_name)>0 and ( length(A.evidence_code)<12 or substr(A.evidence_code,length(A.evidence_code)-2,1)!='8') ) and (A.centre=? or A.centre=?) EOSQL $ST->execute($Reference, $Comparitor, ".$Reference.", ".$Comparitor.")

      Freezer:

      I used commonly-used[1] SQL constructs, so[2] it should be just fine. I used MySQL about 10 years ago, and I seem to recall that it was fairly standard SQL, so I would expect it to work. (Most of the things I remember as lacking (such as nested queries) were added to MySQL years ago.)

      I only mentioned Oracle to let you know that I'm not current on MySQL and that you *might* need to tweak it.

      However, as Corion mentioned in his initial response, there's no substitute for using indexes, benchmarking and any statement analysis feedback your database offers. After all, how the database decides to execute your SQL statement may be markedly different than what you might imagine. For example, I *expect* that the comparison / length / substring may be faster than like. But I have no idea what MySQL's opinion may turn out to be.

      Update: Updated in response to AM's reply. Thanks! [1] I changed "standard SQL" to "commonly-used SQL", and [2] removed "if MySQL uses standard SQL".

      ...roboticus

      When your only tool is a hammer, all problems look like your thumb.

        To nit-pick, != is not standard SQL. <> is. And ANSI SQL has substring(string FROM idx FOR len), as opposed to substr(string, idx, len)

        Anyway, good work on the rewrite. I tried it myself and ended up with a similar statement (albeit with a few extra tables).

      What makes you think that the SQL as shown is specific to Oracle?

      Also, why are you posting nonsensical syntax errors in what looks like it could be meant as Perl code?

      Maybe you want to tell us what syntax errors you actually get?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://992770]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2024-04-19 03:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found