# Example VTICosting implementation

Once you have measured your table function's cost, you can write the VTICosting methods.

Optimizer fine-tuning can be added to the EmployeeTable table function shown before in Example Derby-style table function:

    package com.acme.hrSchema;

    import java.io.Serializable;
    import java.sql.*;

    import org.apache.derby.vti.VTICosting;
    import org.apache.derby.vti.VTIEnvironment;

    /**
     * Tuned table function.
     */
    public class TunedEmployeeTable extends EmployeeTable
        implements VTICosting
    {
        public TunedEmployeeTable() {}

        public double getEstimatedRowCount( VTIEnvironment optimizerState )
            throws SQLException
        {
            return getRowCount( optimizerState );
        }

        public double getEstimatedCostPerInstantiation(
            VTIEnvironment optimizerState ) throws SQLException
        {
            double I = 100.0;  // optimizer imprecision
            double P = 10.0;   // cost per row in milliseconds
            double E = 0.0;    // cost of instantiating the external
                                //   ResultSet
            double N = getRowCount( optimizerState );

            return I * ( ( P * N ) + E );
        }

        public boolean supportsMultipleInstantiations(
            VTIEnvironment optimizerState ) throws SQLException
        {
            return true;
        }

        //////////////////////////////////////////////////////////////////

        private double  getRowCount( VTIEnvironment optimizerState )
            throws SQLException
        {
            String ROW_COUNT_KEY = "rowCountKey";
            Double estimatedRowCount = (Double) getSharedState(
                optimizerState, ROW_COUNT_KEY );

            if ( estimatedRowCount == null )
            {
                Connection        conn = getConnection();
                PreparedStatement ps = conn.prepareStatement(
                    "select count(*) from hrSchema.EmployeeTable" );
                ResultSet         rs = ps.executeQuery();

                rs.next();
                estimatedRowCount = new Double( rs.getDouble( 1 ) );

                setSharedState( optimizerState, ROW_COUNT_KEY,
                    estimatedRowCount );

                rs.close();
                ps.close();
                conn.close();
            }

            return estimatedRowCount.doubleValue();
        }

        private Serializable getSharedState(
            VTIEnvironment optimizerState, String key )
        {
            return (Serializable) optimizerState.getSharedState( key );
        }

        private void setSharedState( VTIEnvironment optimizerState,
            String key, Serializable value )
        {
            optimizerState.setSharedState( key, value );
        }
    }

Parent topic: Optimizer support for Derby-style table functions