You are not using assert/1 in proper way. Prolog has a fast and efficient in memory DB, but as any DB, must be properly indexed. And of course, as any language, avoid repeating the very same operation each time, but format the data once, while preparing the DB.
:- dynamic samples/3.
prepare_db(File) :-
( nonvar(File) ; File = 'GSE2109_BarCode.csv' ),
open(File, read, S),
read_row(S, [_Empty|ColKeys]),
forall(read_row(S, [RowKeyDirty|Samples]),
( clean_rowkey(RowKeyDirty, RowKey),
maplist(store_sample(RowKey), ColKeys, Samples)
)),
close(S).
store_sample(RowKey, ColKey, Sample) :-
assertz(samples(RowKey, ColKey, Sample)).
clean_rowkey(RowKeyDirty, RowKey) :- append(RowKey, ".CEL", RowKeyDirty).
This code assumes that the first row has the very same number of columns as all other rows.
read_row/2 must fetch a row and split in a list of codes lists, I guess your csv_read_file_row_list/2 already does it, but I can't spot your definition in posted code.
Indexing works better with atoms, instead of code lists. atom_codes/2 allows to switch between these representations.
edit
From your comment and additional posted code, I can see my answer wasn't very appropriate. Here is a modified and tested snippet
:- [library(csv)].
:- dynamic samples/3.
:- dynamic column_keys/1.
prepare_db(File) :-
retractall(column_keys(_)),
retractall(samples(_,_,_)),
( nonvar(File) ; File = '/tmp/test.csv' ),
forall(read_row(File, Row), store_row(Row)).
store_row(Row) :-
Row =.. [row|Cols],
( column_keys(ColKeys)
-> Cols = [RowKeyDirty|Samples],
clean_rowkey(RowKeyDirty, RowKey),
maplist(store_sample(RowKey), ColKeys, Samples)
; assertz(column_keys(Cols))
).
store_sample(RowKey, ColKey, Sample) :-
assertz(samples(RowKey, ColKey, Sample)).
clean_rowkey(RowKeyDirty, RowKey) :-
atom_concat(RowKey, '.CEL', RowKeyDirty).
read_row(File, Row) :-
csv_read_file_row(File, Row, [separator(0' ), strip(true), convert(true)]),
writeln(read_row(Row)).
that works for this test file
1007_s_at 1053_at 117_at
GSM102447.CEL 1 0 0
GSM102449.CEL 1 0 0
GSM102451.CEL 1 0 0
GSM102455.CEL 1 0 0
GSM102507.CEL 1 0 1
and yields
?- prepare_db(_).
read_row(row(1007_s_at,1053_at,117_at))
read_row(row(GSM102447.CEL,1,0,0))
read_row(row(GSM102449.CEL,1,0,0))
read_row(row(GSM102451.CEL,1,0,0))
read_row(row(GSM102455.CEL,1,0,0))
read_row(row(GSM102507.CEL,1,0,1))
true.
16 ?- samples(X,Y,Z).
X = 'GSM102447',
Y = '1007_s_at',
Z = 1 ;
X = 'GSM102447',
Y = '1053_at',
Z = 0 ;
...
Of course, the display of read row is just for debug purpose