Prueba esto:
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)
Pase el comando sql solo una vez para todas las filas. Además de la sobrecarga de rendimiento de emitir comandos sql adicionales, tenga en cuenta que el tamaño de la propia cadena sql (en bytes) probablemente empequeñece el tamaño de los datos reales bajo prueba.
El uso de id2 como generador sin la matriz también debería evitar cargar todo el conjunto de datos en la memoria.