The optimizer makes hard-coded guesses about how to calculate the cost of a user-written Derby-style table function. For this reason, the optimizer may place a table function in an inefficient position in the join order. You can give the optimizer more information so that it makes better choices. See "Programming Derby-style table functions" in the Derby Developer's Guide for details.
Using restricted table functions can also improve performance greatly. See "Writing restricted table functions" in the Derby Developer's Guide.