Prova questo:
id2 = csv.reader(open(os.path.join(perf_dir,id_files[1])))
h = tuple(next(id2))
create = '''CREATE TABLE id2 (%s varchar, %s int PRIMARY KEY, %s int)''' % h
insert = '''INSERT INTO id2 (%s, %s, %s) VALUES (%%s, %%s, %%s)''' % h
...
cr.executemany(insert, id2)
Passa il comando sql solo una volta per tutte le righe. Oltre al sovraccarico di prestazioni dell'emissione di comandi sql aggiuntivi, nota che la dimensione della stringa sql stessa (in byte) probabilmente fa impallidire la dimensione dei dati reali sotto test.
L'utilizzo di id2 come generatore senza l'array dovrebbe anche evitare di caricare l'intero set di dati in memoria.