提交 92ccb7c7 编写于 作者: R Ryuta Kamizono

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"]]
```
上级 3101a413
......@@ -75,14 +75,7 @@ def prepare_update_statement(o)
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.
......
......@@ -76,7 +76,13 @@ def compile(node, collector = Arel::Collectors::SQLString.new)
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)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册