Search API node access limitation
My solution was to patch the search api db implementation.

This looks to see whether the field is a one-to-many relationship; if it is, then the table is added for each condition. I presume that this is so that these matches can then be counted and add towards the relevance score. However, for access restriction we're only interested in a single match, and (presumably) shouldn't add this to the score anyway. Therefore for this case there is no need to add a join for each possibility.

The patch below looks for this use case and ensures the user access table is only joined once.

--- a/sites/all/modules/search_api_db/service.inc
+++ b/sites/all/modules/search_api_db/service.inc
@@ -1028,7 +1028,12 @@ class SearchApiDbService extends SearchApiAbstractService {
           $cond-&gt;condition('t.item_id', $query, $f[2] == '&lt;&gt;' || $f[2] == '!=' ? 'NOT IN' : 'IN');
         }
         else {
-          $alias = $this-&gt;getTableAlias($fields[$f[0]], $db_query, search_api_is_list_type($fields[$f[0]]['type']));
+          // the user access node table only needs joining once; we're not interested in
+          // scoring based on access; access is a boolean, so we do not need muliple joins
+          // which can break the query if there are more of them than the SQL engine allows joins
+          // (e.g. MySQL is limited to 64 joins).
+          $rejoin = search_api_is_list_type($fields[$f[0]]['type']) &amp;&amp; ($f[0] != 'search_api_access_node');
+          $alias = $this-&gt;getTableAlias($fields[$f[0]], $db_query, $rejoin);
           $cond-&gt;condition($alias . '.value', $f[1], $f[2]);
         }
       }




EDIT: LOL - or as they did it...

+          $new_join = search_api_is_list_type($field['type'])
+              &amp;&amp; ($filter-&gt;getConjunction() == 'AND'
+                  || empty($first_join[$f[0]]));
+          if ($new_join || empty($tables[$f[0]])) {
+            $tables[$f[0]] = $this-&gt;getTableAlias($field, $db_query, $new_join);
+            $first_join[$f[0]] = TRUE;
+          }
+          $cond-&gt;condition($tables[$f[0]] . '.' . $field['column'], $f[1], $f[2]);


Answer is: upgrade module to v7.x-1.0!