diff --git a/core/lib/Drupal/Core/Menu/MenuTreeStorage.php b/core/lib/Drupal/Core/Menu/MenuTreeStorage.php
index 0b11f86..f83f5ac 100644
--- a/core/lib/Drupal/Core/Menu/MenuTreeStorage.php
+++ b/core/lib/Drupal/Core/Menu/MenuTreeStorage.php
@@ -282,27 +282,38 @@ public function save(array $link) {
    *   depth.
    */
   protected function doSave(array $link) {
-    $original = $this->loadFull($link['id']);
-    // @todo Should we just return here if the link values match the original
-    //   values completely?
-    //   https://www.drupal.org/node/2302137
     $affected_menus = [];
 
+    // Get the existing definition if it exist. This does not use
+    // self::loadFull() because we want to compare with $link after calling
+    // self::preSave() and therefore we need to avoid the unserialization.
+    $query = $this->connection->select($this->table, $this->options);
+    $query->fields($this->table);
+    $query->condition('id', $link['id']);
+    $original = $this->safeExecuteSelect($query)->fetchAssoc();
+
+    if ($original) {
+      $link['mlid'] = $original['mlid'];
+      $link['has_children'] = $original['has_children'];
+      $affected_menus[$original['menu_name']] = $original['menu_name'];
+      $fields = $this->preSave($link, $original);
+      // If $link matches the $original data then exit early as there are no
+      // changes to make.
+      if (array_diff_assoc($fields, $original) === []) {
+        return $affected_menus;
+      }
+    }
+
     $transaction = $this->connection->startTransaction();
     try {
-      if ($original) {
-        $link['mlid'] = $original['mlid'];
-        $link['has_children'] = $original['has_children'];
-        $affected_menus[$original['menu_name']] = $original['menu_name'];
-      }
-      else {
+      if (!$original) {
         // Generate a new mlid.
         $options = ['return' => Database::RETURN_INSERT_ID] + $this->options;
         $link['mlid'] = $this->connection->insert($this->table, $options)
           ->fields(['id' => $link['id'], 'menu_name' => $link['menu_name']])
           ->execute();
+        $fields = $this->preSave($link, []);
       }
-      $fields = $this->preSave($link, $original);
       // We may be moving the link to a new menu.
       $affected_menus[$fields['menu_name']] = $fields['menu_name'];
       $query = $this->connection->update($this->table, $this->options);
