[Dbix-class] MySQL DELETE with LIMIT
Peter Rabbitson
rabbit+dbic at rabbit.us
Tue Aug 18 12:21:42 GMT 2015
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!
More information about the DBIx-Class
mailing list