Reduce the number of joins required to find upstream / downstream neurons
Reduce the number of joins required to find upstream / downstream neurons

This fix is required because of a performance problem introduced
by 2dadf996f2aa7d96c13a6f77fb8f665dfb1a99ef.  That commit only
changed the related_name of two fields, but seems to be causing
a different query to be generated.  For example, the bad query is:

    [sql] SELECT ...
      FROM "class_instance"
      INNER JOIN "class_instance_class_instance" ON ("class_instance"."id" = "class_instance_class_instance"."class_instance_b")
      INNER JOIN "class_instance" T4 ON ("class_instance_class_instance"."class_instance_a" = T4."id")
      INNER JOIN "class_instance_class_instance" T5 ON (T4."id" = T5."class_instance_a")
      INNER JOIN "class_instance" T6 ON (T5."class_instance_b" = T6."id")
      INNER JOIN "class_instance_class_instance" T7 ON (T6."id" = T7."class_instance_a")
      INNER JOIN "relation" ON (T7."relation_id" = "relation"."id")
      INNER JOIN "relation" T9 ON ("class_instance_class_instance"."relation_id" = T9."id")
      INNER JOIN "relation" T10 ON (T5."relation_id" = T10."id")
      INNER JOIN "class" ON (T4."class_id" = "class"."id")
      INNER JOIN "class" T12 ON ("class_instance"."class_id" = T12."id")
      INNER JOIN "class_instance" T13 ON (T5."class_instance_b" = T13."id")
      INNER JOIN "class" T14 ON (T13."class_id" = T14."id")
      INNER JOIN "class_instance" T15 ON (T5."class_instance_b" = T15."id")
      INNER JOIN "class_instance_class_instance" T16 ON (T15."id" = T16."class_instance_a")
      WHERE ("class_instance"."project_id" = 4
             AND "relation"."relation_name" = model_of
             AND T9."relation_name" = presynaptic_to
             AND T10."relation_name" = part_of
             AND "class"."class_name" = presynaptic terminal
             AND T12."class_name" = synapse
             AND T14."class_name" = skeleton
             AND T16."class_instance_b" = 14638336)

... while the good query is:

    [sql] SELECT ...
      FROM "class_instance"
      INNER JOIN "class_instance_class_instance" ON ("class_instance"."id" = "class_instance_class_instance"."class_instance_b")
      INNER JOIN "class_instance" T4 ON ("class_instance_class_instance"."class_instance_a" = T4."id")
      INNER JOIN "class_instance_class_instance" T5 ON (T4."id" = T5."class_instance_a")
      INNER JOIN "class_instance" T6 ON (T5."class_instance_b" = T6."id")
      INNER JOIN "class_instance_class_instance" T7 ON (T6."id" = T7."class_instance_a")
      INNER JOIN "relation" ON ("class_instance_class_instance"."relation_id" = "relation"."id")
      INNER JOIN "relation" T10 ON (T5."relation_id" = T10."id")
      INNER JOIN "class_instance" T11 ON (T5."class_instance_b" = T11."id")
      INNER JOIN "class" ON (T11."class_id" = "class"."id")
      INNER JOIN "class_instance" T13 ON (T5."class_instance_b" = T13."id")
      INNER JOIN "class_instance_class_instance" T14 ON (T13."id" = T14."class_instance_a")
      INNER JOIN "relation" T15 ON (T14."relation_id" = T15."id")
      INNER JOIN "class" T16 ON ("class_instance"."class_id" = T16."id")
      INNER JOIN "class" T17 ON (T4."class_id" = T17."id")
      WHERE ("class_instance"."project_id" = 4
             AND T7."class_instance_b" = 14638336
             AND "relation"."relation_name" = presynaptic_to
             AND T10."relation_name" = part_of
             AND "class"."class_name" = skeleton
             AND T15."relation_name" = model_of
             AND T16."class_name" = synapse
             AND T17."class_name" = presynaptic terminal)

... the difference between those two being:

--- bad-query	2011-12-07 09:36:12.901880761 +0100
+++ good-query	2011-12-07 09:39:06.211029090 +0100
@@ -5,20 +5,20 @@
       INNER JOIN "class_instance_class_instance" T5 ON (T4."id" = T5."class_instance_a")
       INNER JOIN "class_instance" T6 ON (T5."class_instance_b" = T6."id")
       INNER JOIN "class_instance_class_instance" T7 ON (T6."id" = T7."class_instance_a")
-      INNER JOIN "relation" ON (T7."relation_id" = "relation"."id")
-      INNER JOIN "relation" T9 ON ("class_instance_class_instance"."relation_id" = T9."id")
+      INNER JOIN "relation" ON ("class_instance_class_instance"."relation_id" = "relation"."id")
       INNER JOIN "relation" T10 ON (T5."relation_id" = T10."id")
-      INNER JOIN "class" ON (T4."class_id" = "class"."id")
-      INNER JOIN "class" T12 ON ("class_instance"."class_id" = T12."id")
+      INNER JOIN "class_instance" T11 ON (T5."class_instance_b" = T11."id")
+      INNER JOIN "class" ON (T11."class_id" = "class"."id")
       INNER JOIN "class_instance" T13 ON (T5."class_instance_b" = T13."id")
-      INNER JOIN "class" T14 ON (T13."class_id" = T14."id")
-      INNER JOIN "class_instance" T15 ON (T5."class_instance_b" = T15."id")
-      INNER JOIN "class_instance_class_instance" T16 ON (T15."id" = T16."class_instance_a")
+      INNER JOIN "class_instance_class_instance" T14 ON (T13."id" = T14."class_instance_a")
+      INNER JOIN "relation" T15 ON (T14."relation_id" = T15."id")
+      INNER JOIN "class" T16 ON ("class_instance"."class_id" = T16."id")
+      INNER JOIN "class" T17 ON (T4."class_id" = T17."id")
       WHERE ("class_instance"."project_id" = 4
-             AND "relation"."relation_name" = model_of
-             AND T9."relation_name" = presynaptic_to
+             AND T7."class_instance_b" = 14638336
+             AND "relation"."relation_name" = presynaptic_to
              AND T10."relation_name" = part_of
-             AND "class"."class_name" = presynaptic terminal
-             AND T12."class_name" = synapse
-             AND T14."class_name" = skeleton
-             AND T16."class_instance_b" = 14638336)
+             AND "class"."class_name" = skeleton
+             AND T15."relation_name" = model_of
+             AND T16."class_name" = synapse
+             AND T17."class_name" = presynaptic terminal)

This doesn't make any sense to me, but we need this to be fixed as a priority.
The difference between the good queries and the bad queries seems to be
related to the joins to the class and relation table, so this commit removes
those joins by adding two queries to cache the (relation|class) name
to id mapping before this one.

Obviously, this is a poor solution, since we still don't understand why a
simple change of name should cause a degenerate query.

fzadow/CATMAID,htem/CATMAID,htem/CATMAID,htem/CATMAID,fzadow/CATMAID,htem/CATMAID,fzadow/CATMAID,fzadow/CATMAID