On 08/18/2015 01:59 PM, Dmitry Bigunyak wrote:
Hi there,

I was very surprised to see the SQL statement which is generated when trying to 
delete some data with LIMIT clause.
My DBIC code:

my $rows = $rs->search(
     { state => 'D' },
     { rows => 10000 }
)->delete();

The SQL statement I get is this:

DELETE FROM cache WHERE (  id IN ( SELECT * FROM ( SELECT me.id FROM cache me 
WHERE ( state = ? ) LIMIT ? ) `_forced_double_subquery` )  ): 'D', '10000'

Which is a bit different from expected simple:

DELETE FROM cache WHERE state = 'D' LIMIT 10000;

The problem with the generated SQL is performance of course, on a table with 
just 100k records it's already 3 times slower than the second version.


During limited testing with the second version, it was discovered it does not perform reliably across a variety of engines. Hence the subquery variant was chosen as the one that "works in virtually all circumstances"

It is not specified which engine are you using, but the emitted SQL makes me think you are on MySQL. This engine is known to suffer from a number of bugs where it would throw away the ORDER BY in partial UPDATE/DELETE cases (and LIMIT without ORDER BY makes no sense in almost any workload).


If this is a known drawback and is it possible to get the normal simple query with 
DBIC or my only option here is to fall back to DBI with schema->storage->dbh ?

I would be interested in a patch that allows for leaner SQL *provided* it detects a fixed-up MySQL version *AND* is covered with tests for each and every conceivable scenario.

If you would like to do the (considerable) legwork, I would be more than happy to provide you with extra information and guidance.

Cheers!


_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@lists.scsys.co.uk

Reply via email to