Re: bug report: slow getColumnTypeName

Поиск
Список
Период
Сортировка
От Luis Flores
Тема Re: bug report: slow getColumnTypeName
Дата
Msg-id CA+nXnG_Ma7c2kjsQJPDQMwXtsJHPW+7U0G3dQSzH8YpFMxaVSQ@mail.gmail.com
обсуждение исходный текст
Ответ на Re: bug report: slow getColumnTypeName  (Luis Flores <luiscamposflores@gmail.com>)
Ответы Re: bug report: slow getColumnTypeName  (Eyal Wilde <eyal.wilde@gmail.com>)
Список pgsql-jdbc
I'm sorry, but I'm a bit sleepy ...

I believe the code is more readable/better like this:

    public String getColumnTypeName(int column) throws SQLException
    {
        String type = getPGType(column);
        if ( ( "int4".equals(type) && isAutoIncrement(column)) {
            type = "serial";
        } else if ("int8".equals(type) && isAutoIncrement(column)) {
            type "bigserial";
        }

        return type;
    }

Luis Flores

On Wed, Oct 10, 2012 at 11:39 PM, Luis Flores
<luiscamposflores@gmail.com> wrote:
> I've looked at the AbstractJdbc2ResultSetMetadata getColumnTypeName,
> for version 1000 and 802.
>
> The change is simple, there is an extra call to isAutoIncrement, to be
> able to return correct values in the serial and bigserial cases.
>
> The isAutoIncrement call is slow because it triggers
> fetchFieldMetadata, witch get all metada for all fields.
>
> One simple optimization is to change the current method to:
>
>     public String getColumnTypeName(int column) throws SQLException
>     {
>         String type = getPGType(column);
>         if ( ( "int4".equals(type) || "int8".equals(type) ) &&
> isAutoIncrement(column)) {
>             if ("int4".equals(type)) {
>                 return "serial";
>             } else if ("int8".equals(type)) {
>                 return "bigserial";
>             }
>         }
>
>         return type;
>     }
>
> In this case, the isAutoIncrement is only called on int4 and int8
> columns, causing the performance for all the other column types to
> remain the same.
>
> May they are better options, but I think this change is good, it
> delays fetching metadata, and speeds up the method, without side
> effects.
>
> Luis Flores
>
> On Wed, Oct 10, 2012 at 11:10 PM, Luis Flores
> <luiscamposflores@gmail.com> wrote:
>> I also confirm the performance regression.
>>
>> Testing on Fedora17 64bit + PostgreSQL 9.1 + jdk 1.6.0_33, localhost
>> server, I get these numbers:
>> driver 802
>> getColumnType time (ms): 2777
>> getColumnTypeName time (ms): 1847
>> both time (ms): 1948
>>
>> driver 903
>> getColumnType time (ms): 3044
>> getColumnTypeName time (ms): 27123
>> both time (ms): 25142
>>
>> driver 1000
>> getColumnType time (ms): 2928
>> getColumnTypeName time (ms): 27214
>> both time (ms): 26407
>>
>> During the getColumnTypeName tests postgresql daemon used 100% cpu time.
>>
>> Here is the full test class:
>>
>> import java.sql.Connection;
>> import java.sql.DriverManager;
>> import java.sql.ResultSet;
>> import java.sql.ResultSetMetaData;
>> import java.sql.Statement;
>>
>>
>> public class Main
>> {
>>         public static void main( String arg[] )
>>                 throws Exception
>>         {
>>                 Class.forName( "org.postgresql.Driver" );
>>                 Connection conn = DriverManager.getConnection(
>> "jdbc:postgresql://localhost/test", "postgres", "" );
>>                 Statement create = conn.createStatement();
>>                 create.execute( "CREATE TABLE t(id SERIAL, name VARCHAR);" );
>>                 create.close();
>>                 long l = System.currentTimeMillis();
>>                 for( int i = 0; i < 10000; ++i )
>>                 {
>>                         Statement stm = conn.createStatement();
>>                         stm.execute( "SELECT id, name FROM t;" );
>>                         ResultSet rs = stm.getResultSet();
>>                         ResultSetMetaData rsmd = rs.getMetaData();
>>                         rsmd.getColumnType( 1 );
>> //                      rsmd.getColumnTypeName( 1 );
>>                         rs.close();
>>                         stm.close();
>>                 }
>>                 System.out.println( "getColumnType time (ms): " + (
>> System.currentTimeMillis() - l ) );
>>                 l = System.currentTimeMillis();
>>                 for( int i = 0; i < 10000; ++i )
>>                 {
>>                         Statement stm = conn.createStatement();
>>                         stm.execute( "SELECT id, name FROM t;" );
>>                         ResultSet rs = stm.getResultSet();
>>                         ResultSetMetaData rsmd = rs.getMetaData();
>> //                      rsmd.getColumnType( 1 );
>>                         rsmd.getColumnTypeName( 1 );
>>                         rs.close();
>>                         stm.close();
>>                 }
>>                 System.out.println( "getColumnTypeName time (ms): " + (
>> System.currentTimeMillis() - l ) );
>>                 l = System.currentTimeMillis();
>>                 for( int i = 0; i < 10000; ++i )
>>                 {
>>                         Statement stm = conn.createStatement();
>>                         stm.execute( "SELECT id, name FROM t;" );
>>                         ResultSet rs = stm.getResultSet();
>>                         ResultSetMetaData rsmd = rs.getMetaData();
>>                         rsmd.getColumnType( 1 );
>>                         rsmd.getColumnTypeName( 1 );
>>                         rs.close();
>>                         stm.close();
>>                 }
>>                 System.out.println( "both time (ms): " + ( System.currentTimeMillis() - l ) );
>>                 Statement drop = conn.createStatement();
>>                 drop.execute( "DROP TABLE t;" );
>>                 drop.close();
>>                 conn.close();
>>         }
>> }
>>
>>
>> Luis Flores
>>
>> On Tue, Oct 9, 2012 at 5:48 PM, dmp <danap@ttc-cmc.net> wrote:
>>> Eyal Wilde wrote:
>>>>
>>>> I verified with wireshark that  getColumnTypeName indeed do a request to
>>>> the postgres server. This happens with 9.1-901 and 9.1-903 BUT NOT WITH
>>>> 9.0-801!!
>>>>
>>>> So, the reason for the slowness seems to be obviouse now.
>>>>
>>>> it will take me some time to wrap up it into a test case. I would realy
>>>> like to help, but please let me know if it's realy necessary.
>>>>
>>>> On Oct 5, 2012 1:07 AM, "Eyal Wilde" <eyal@impactsoft.co.il
>>>> <mailto:eyal@impactsoft.co.il>> wrote:
>>>>
>>>>
>>>>                          ResultSetMetaData __md = __rs.getMetaData();
>>>>       //this is fine
>>>>                          String __sf1name = __md.getColumnName(1);
>>>>        //this is fine
>>>>                          int __if1type = __md.getColumnType(1);
>>>>             //this is fine
>>>>                          String __sf1type =
>>>>     __md.getColumnTypeName(1); //this is SLOW!! ~15msec
>>>>
>>>>     postgres server version is 9.1.5
>>>>     jdbc version, i checked both 9.1-901 and 9.1-903
>>>>     and... BTW, 9.0-801 works good (while connected pg9.1)!
>>>
>>>
>>> There does appear to be a change in the code that may have created the
>>> slowness that you are observing. Please try a a test case in which two
>>> back to back getColumnTypeName() calls are made. Is there a difference
>>> in time between the first and second and is there still on the second
>>> call a request to the postgres server.
>>>
>>> The code between 9.0-801 and later version does have a change in it
>>> that looks like for the caching for field metadata through
>>> fetchFieldMetaData().
>>> That method is called in the later versions for getColumnTypeName()
>>> with isAutoIncrement(), with was also added in later versions.
>>>
>>> danap.
>>>
>>>
>>>
>>>
>>> --
>>> Sent via pgsql-jdbc mailing list (pgsql-jdbc@postgresql.org)
>>> To make changes to your subscription:
>>> http://www.postgresql.org/mailpref/pgsql-jdbc


В списке pgsql-jdbc по дате отправления:

Предыдущее
От: Luis Flores
Дата:
Сообщение: Re: bug report: slow getColumnTypeName
Следующее
От: dmp
Дата:
Сообщение: Re: bug report: slow getColumnTypeName