Comparação para persistir data e hora, usar timestamp ou milisegundos (long)?

Senhores, boa noite.

Realizei um teste para comparar qual é o mais performático para usar nas aplicaçoes, se persistir timestamp ou milisegundos (long - bigint);

Teste										Milisegundos				Timestamp
Inserção de  10.0001 itens (tabela vazia)                    32,732					  15,298 
Inserção de  10.0001 itens (tabela com 10.0001)         8,711			            		  23,996
Inserção de 100.0001 itens (tabela com 10.0001)       117,912	    			           81,167
Pesquisa de  10.0001 itens                                        3,514						   8,615
Pesquisa de 110.0001 itens					       5,112			           		  11,034	 										  	

Considerações
Para inserção: Usar o timestamp é cerca de 35% mais performático.
Para pesquisa: Usar milisegundo é cerca de 50 % mais performático.
Deve ser analisado qual será a característica mais usada no sistema, no meu caso, será a pesquisa.

Java 1.6
Postgress 8.4
Jdbc

Abaixo meu Junit:

public class CaseTestTimestampOrBigInt extends TestCase {

	public void testInit() throws ConnectBaseException, SQLException, InterruptedException {
		System.out.println("go in timestamp...");
		Connection connection = ConnectionUtils.createConnection();
		// call method for test
		connection.close();
		System.out.println("finish!");
	}
        // the first and the last date
	public void searchInMilisegundos(Connection connection) throws SQLException {
		Statement statement = connection.createStatement();
		ResultSet executeQuery = statement.executeQuery("SELECT * FROM testemilisegundos where dt BETWEEN 1366664441713 and 301192656056506");
		while (executeQuery.next() == true) {
			long long1 = executeQuery.getLong("dt");
			System.out.println(long1);
		}
		executeQuery.close();
		statement.close();

	}
        // the first and the last date
	public void searchInTimestamp(Connection connection) throws SQLException {
		Statement statement = connection.createStatement();
		ResultSet executeQuery = statement.executeQuery("select * from testedate where dt between '2013-04-22 18:00:23.354' and '11514-06-01 23:40:23.354'");
		while (executeQuery.next() == true) {
			Timestamp long1 = executeQuery.getTimestamp("dt");
			System.out.println(long1);
		}
		executeQuery.close();
		statement.close();
	}

	public void insertInMilisegundos(Connection connection, int quantidade) throws SQLException {

		Statement statement = connection.createStatement();
		Calendar calendar = GregorianCalendar.getInstance();
		for (int index = 0; index <= quantidade; index++) {
			calendar.set(Calendar.MINUTE, index);
			long timeInMillis = calendar.getTimeInMillis();

			QueryBuilder sqlInsert = new QueryBuilder("INSERT INTO testeMilisegundos VALUES (#id#,#dt#)");
			sqlInsert.setParameter("#id#", index);
			sqlInsert.setParameter("#dt#", timeInMillis);
			statement.executeUpdate(sqlInsert.toString());
		}
		statement.close();
	}

	public void insertInTimestamp(Connection connection, int quantidade) throws SQLException {

		Statement statement = connection.createStatement();
		Calendar calendar = GregorianCalendar.getInstance();
		for (int index = 0; index <= quantidade; index++) {
			calendar.set(Calendar.MINUTE, index);
			Timestamp timestamp = new Timestamp(calendar.getTimeInMillis());

			QueryBuilder sqlInsert = new QueryBuilder("INSERT INTO  testeDate VALUES (#id#,#dt#)");
			sqlInsert.setParameter("#id#", index);
			sqlInsert.setParameter("#dt#", timestamp);
			statement.executeUpdate(sqlInsert.toString());
		}
		statement.close();
	}

	public void createTables(Connection conn) throws ConnectBaseException, SQLException {

		Statement statement = conn.createStatement();
		StringBuilder sbInMilissegundos = new StringBuilder();
		sbInMilissegundos.append("create table testeMilisegundos( ");
		sbInMilissegundos.append("	id 	integer 	not null, ");
		sbInMilissegundos.append("	dt 	bigint 	not null ");
		sbInMilissegundos.append(") ");
		statement.executeUpdate(sbInMilissegundos.toString());

		StringBuilder sbInTimestamp = new StringBuilder();
		sbInTimestamp.append(" ");
		sbInTimestamp.append("create table testeDate( ");
		sbInTimestamp.append("	id 	integer 	not null, ");
		sbInTimestamp.append("	dt 	timestamp 	not null ");
		sbInTimestamp.append(") ");
		statement.executeUpdate(sbInTimestamp.toString());

		statement.close();
	}

}

Ps. Meu query builder apenas monta a query (substitui #campo# pelo valor)

Todos os comentários são bem vindos!!

Se sua preocupação por performance for exagerada, use o tempo em millis. Ele é um número inteiro, e com certeza será melhor indexado pelo banco.

Por outro lado, isso vai te dificultar logs, busca por dia específico da semana (todos os registros que ocorreram na terça, por exemplo) ou escrever SQLs na forma de texto quando estiver usando a aplicação de banco. Em 99% dos casos, não recomendo. Use sempre o tipo que descreve melhor seus dados (DATE se precisar só da data, TIME se precisar só da hora e TIMESTAMP se precisar dos dois).

[quote=ViniGodoy]Se sua preocupação por performance for exagerada, use o tempo em millis. Ele é um número inteiro, e com certeza será melhor indexado pelo banco.

Por outro lado, isso vai te dificultar logs, busca por dia específico da semana (todos os registros que ocorreram na terça, por exemplo) ou escrever SQLs na forma de texto quando estiver usando a aplicação de banco. Em 99% dos casos, não recomendo. Use sempre o tipo que descreve melhor seus dados (DATE se precisar só da data, TIME se precisar só da hora e TIMESTAMP se precisar dos dois).[/quote]

Ótimas considerações Vini!!

No meu caso sempre usarei intervalo de datas, também sempre necessário converter as datas em timestamp para pesquisa na base, independentemente do client.