1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Improve DELETE with JOIN handling to avoid subqueries if possible

Before:

```
  Pet Destroy (0.8ms)  DELETE FROM `pets` WHERE `pets`.`pet_id` IN (SELECT `pet_id` FROM (SELECT DISTINCT `pets`.`pet_id` FROM `pets` LEFT OUTER JOIN `toys` ON `toys`.`pet_id` = `pets`.`pet_id` WHERE `toys`.`name` = ?) AS __active_record_temp)  [["name", "Bone"]]
```

After:

```
  Pet Destroy (1.0ms)  DELETE `pets` FROM `pets` LEFT OUTER JOIN `toys` ON `toys`.`pet_id` = `pets`.`pet_id` WHERE `toys`.`name` = ?  [["name", "Bone"]]
```
This commit is contained in:
Ryuta Kamizono 2018-10-10 05:31:20 +09:00
parent 3101a4136b
commit 92ccb7c75f
2 changed files with 8 additions and 9 deletions

View file

@ -75,14 +75,7 @@ module Arel # :nodoc: all
o
end
end
def prepare_delete_statement(o)
if o.offset || has_join_sources?(o)
super
else
o
end
end
alias :prepare_delete_statement :prepare_update_statement
# MySQL is too stupid to create a temporary table for use subquery, so we have
# to give it some prompting in the form of a subsubquery.

View file

@ -76,7 +76,13 @@ module Arel # :nodoc: all
def visit_Arel_Nodes_DeleteStatement(o, collector)
o = prepare_delete_statement(o)
collector << "DELETE FROM "
if has_join_sources?(o)
collector << "DELETE "
visit o.relation.left, collector
collector << " FROM "
else
collector << "DELETE FROM "
end
collector = visit o.relation, collector
collect_where_for(o, collector)