diff --git a/include/class.orm.php b/include/class.orm.php
index c71f0e1e60f4e8e5e0aac99a8bfca98d89fcba8b..037966a45dc97ee717e93245a16972b867d866f5 100644
--- a/include/class.orm.php
+++ b/include/class.orm.php
@@ -229,6 +229,17 @@ class ModelMeta implements ArrayAccess {
         return $this->fields;
     }
 
+    function getByPath($path) {
+        if (is_string($path))
+            $path = explode('__', $path);
+        $root = $this;
+        foreach ($path as $P) {
+            list($root, ) = $root['joins'][$P]['fkey'];
+            $root = $root::getMeta();
+        }
+        return $root;
+    }
+
     /**
      * Create a new instance of the model, optionally hydrating it with the
      * given hash table. The constructor is not called, which leaves the
@@ -2246,9 +2257,22 @@ class SqlCompiler {
             // Handle relationship comparisons with model objects
             elseif ($value instanceof VerySimpleModel) {
                 $criteria = array();
-                foreach ($value->pk as $f=>$v) {
-                    $f = $field . '__' . $f;
-                    $criteria[$f] = $v;
+                // Avoid a join if possible. Use the local side of the
+                // relationship
+                if (count($value->pk) === 1) {
+                    $path = explode('__', $field);
+                    $relationship = array_pop($path);
+                    $lmodel = $model::getMeta()->getByPath($path);
+                    $local = $lmodel['joins'][$relationship]['local'];
+                    $path = $path ? (implode('__', $path) . '__') : '';
+                    foreach ($value->pk as $v) {
+                        $criteria["{$path}{$local}"] = $v;
+                   }
+                }
+                else {
+                    foreach ($value->pk as $f=>$v) {
+                        $criteria["{$field}__{$f}"] = $v;
+                    }
                 }
                 $filter[] = $this->compileQ(new Q($criteria), $model, $slot);
             }