http://www.perlmonks.org?node_id=1039604


in reply to DBI placeholders and like statement

This works on MySQL ;
$query = 'select name from my_table where name like ?'; my $sth = $dbh->prepare($query); $sth->execute('Jo%');
poj

Replies are listed 'Best First'.
Re^2: DBI placeholders and like statement
by jfroebe (Parson) on Jun 18, 2013 at 17:08 UTC

    Don't I have egg on my face! :) I was putting the percent sign in the query itself.

    Thanks again!

    Jason L. Froebe

    Blog, Tech Blog

      Well, you could say:
      where name like ? || '%'
      But that still won't use an index on the column since the query optimizer doesn't know where any other wildcard will be, whereas hardcoding the entire argument might use an index:
      where name like 'abc%'
        where name like ? || '%'
        

        But that still won't use an index [...]

        Well, it depends.

        From PostgreSQL 9.1 onwards, indexes (made by the trigram extension pg_trgm, an extension that comes with postgres) can be used in like searches. (careful, trigram indexes are large, and therefore not always appropriate).

        A test with a 1-column table, filled with 80-characters 'random' strings; 1 million rows. There happened to be two rows that start with 'erix', so I'll use those as search target (i.e.: where txt like 'erix%').

        -- index created like this: create index azjunk6_trgm_re_idx on azjunk6 using gin (txt gin_trgm_ops); -- running a psql session, showing both -- the regular output, and the EXPLAIN: $ psql Timing is on. psql (9.2.4) Type "help" for help. testdb=# prepare ps(text) as select txt from azjunk6 where txt like $1 || '%'; --> $1 is ? in +DBI/DBD::Pg PREPARE Time: 13.785 ms testdb=# execute ps('erix'); txt ---------------------------------------------------------------------- +------------ erixeweq jp ayoyu marqnrjr ughinmfwklvmzxtrfafy mvwf ond wrz lg yso +tkgli ne n erix onka fp ax erk ddcduajmv yrltcfjsfghlt pq cmdfximql jj ckyzhpwhc +q zkakna (2 rows) Time: 54.482 ms testdb=# explain analyze execute ps('erix'); QUERY PLAN ---------------------------------------------------------------------- +------------------------------------------------------------- Bitmap Heap Scan on azjunk6 (cost=108.78..484.93 rows=100 width=81) +(actual time=48.901..48.913 rows=2 loops=1) Recheck Cond: (txt ~~ 'erix%'::text) Rows Removed by Index Recheck: 16 -> Bitmap Index Scan on azjunk6_trgm_re_idx (cost=0.00..108.75 ro +ws=100 width=0) (actual time=48.882..48.882 rows=18 loops=1) Index Cond: (txt ~~ 'erix%'::text) Total runtime: 48.957 ms (6 rows) Time: 49.714 ms -- look mum no hints testdb=#

        ( And yes, it is faster: with the index removed, it takes 147.060 ms )

        Even better: PostgreSQL 9.3 (in beta ATM) lets trgm index on regexen.

        Depending on the DBMS, you could give it an index hint: from tableA (index ndx). You are correct though, most optimizers would simply give it a hard coded selectivity rating which almost always guarantees that an index won't be chosen for that particular column.

        Jason L. Froebe

        Blog, Tech Blog

      Don't worry about it. First time I tried using like with placeholders I did the same thing. :)