
I have a table f_trigger with 171,452,378 records. It has fields script_id
and machine_uuid (and other fields not used here).
I want to run
select script_id,count(distinct machine_uuid) from f_trigger group by
script_id;
First, though, let's get the number of expected records only:
select count(*) from (select script_id,count(distinct machine_uuid) from
f_trigger group by script_id) as subq;
+------+
| L7 |
+======+
| 208 |
+------+
1 tuple (359.124ms)
Very nice.
Let's explain the query before I run it:
explain select script_id,count(distinct machine_uuid) from f_trigger group
by script_id;
+-------------------------------------------------------------------------------+
| mal
|
+===============================================================================+
| function user.s0_1{autoCommit=true}():void;
|
| X_21 := nil:bat[:oid,:str];
|
| X_39:bat[:oid,:wrd] := nil:bat[:oid,:wrd];
|
| barrier X_596 := language.dataflow();
|
| X_2 := sql.mvc();
|
| X_12:bat[:oid,:str] := sql.bind(X_2,"sys","f_trigger","script_id",0);
|
| X_10:bat[:oid,:str] := sql.bind(X_2,"sys","f_trigger","script_id",2);
|
| X_14 := algebra.kdifference(X_12,X_10);
|
| X_15 := algebra.kunion(X_14,X_10);
|
| X_9:bat[:oid,:str] := sql.bind(X_2,"sys","f_trigger","script_id",1);
|
| X_16 := algebra.kunion(X_15,X_9);
|
| X_5:bat[:oid,:oid] := sql.bind_dbat(X_2,"sys","f_trigger",1);
|
| X_8 := bat.reverse(X_5);
|
| X_17 := algebra.kdifference(X_16,X_8);
|
| (ext28,grp26) := group.done(X_17);
|
| X_20 := bat.mirror(ext28);
|
| X_21 := algebra.join(X_20,X_17);
|
| X_29:bat[:oid,:str] :=
sql.bind(X_2,"sys","f_trigger","machine_uuid",0); |
| X_30 := algebra.selectNotNil(X_29);
|
| X_26:bat[:oid,:str] :=
sql.bind(X_2,"sys","f_trigger","machine_uuid",2); |
| X_31 := algebra.kdifference(X_30,X_26);
|
| X_28 := algebra.selectNotNil(X_26);
|
| X_32 := algebra.kunion(X_31,X_28);
|
| X_24:bat[:oid,:str] :=
sql.bind(X_2,"sys","f_trigger","machine_uuid",1); |
| X_25 := algebra.selectNotNil(X_24);
|
| X_33 := algebra.kunion(X_32,X_25);
|
| X_34 := algebra.kdifference(X_33,X_8);
|
| (X_35,grp55) := group.derive(ext28,grp26,X_34);
|
| X_37 := bat.mirror(X_35);
|
| X_38 := algebra.join(X_37,X_34);
|
| X_39:bat[:oid,:wrd] := aggr.count(X_38,grp26,X_20);
|
| exit X_596;
|
| X_40 := sql.resultSet(2,1,X_21);
|
| sql.rsColumn(X_40,"sys.f_trigger","script_id","varchar",32768,0,X_21);
|
| sql.rsColumn(X_40,"sys.f_trigger","L10","wrd",64,0,X_39);
|
| X_53 := io.stdout();
|
| sql.exportResult(X_53,X_40);
|
| end s0_1;
|
+-------------------------------------------------------------------------------+
38 tuples (3.136ms)
Running the query takes a very long time. While the query is running, I
notice VERY heavy disk writes, and almost no reads and almost no CPU
activity.
Based on other information on the mailing list, I suspect the query
generates intermediate data that gets writted to disk (instead of kept in
memory).
We are running monetdb on a 32 core linux machine with 256 GB of RAM and a
fast raid array. Memory usage is under 20%, so I would not expect monetdb to
be writing to disk so much (50-500MB/s writes)...
Database settings:
shared default yes
nthreads local 32
optpipe local recycler_pipe
master default no
slave default <unknown>
readonly local yes
Stethoscope output:
[1] # event, time, thread, usec, stmt, # name
[1] [ 256, "14:02:38.525477", 2, 0,
"calc.str(\"script_id\");" ]
[1] [ 257, "14:02:38.525477", 2, 134,
"calc.str(\"script_id\");" ]
[1] [ 258, "14:02:38.525634", 2, 0,
"calc.str(\"f_trigger\");" ]
[1] [ 259, "14:02:38.525634", 2, 18,
"calc.str(\"f_trigger\");" ]
[1] [ 260, "14:02:38.525670", 2, 0,
"calc.str(\"script_id\");" ]
[1] [ 261, "14:02:38.525670", 2, 16,
"calc.str(\"script_id\");" ]
[1] [ 262, "14:02:38.525704", 2, 0,
"calc.str(\"f_trigger\");" ]
[1] [ 263, "14:02:38.525704", 2, 17,
"calc.str(\"f_trigger\");" ]
[1] [ 264, "14:02:38.525740", 2, 0,
"calc.str(\"script_id\");" ]
[1] [ 265, "14:02:38.525740", 2, 17,
"calc.str(\"script_id\");" ]
[1] [ 266, "14:02:38.525777", 2, 0,
"calc.str(\"f_trigger\");" ]
[1] [ 267, "14:02:38.525777", 2, 19,
"calc.str(\"f_trigger\");" ]
[1] [ 268, "14:02:38.525812", 2, 0,
"calc.str(\"script_id\");" ]
[1] [ 269, "14:02:38.525812", 2, 19,
"calc.str(\"script_id\");" ]
[1] [ 270, "14:02:38.525848", 2, 0,
"calc.str(\"f_trigger\");" ]
[1] [ 271, "14:02:38.525848", 2, 19,
"calc.str(\"f_trigger\");" ]
[1] [ 272, "14:02:38.525884", 2, 0,
"calc.str(\"L11\");" ]
[1] [ 273, "14:02:38.525884", 2, 19,
"calc.str(\"L11\");" ]
[1] [ 274, "14:02:38.525925", 2, 0,
"calc.str(\"f_trigger\");" ]
[1] [ 275, "14:02:38.525925", 2, 20,
"calc.str(\"f_trigger\");" ]
[1] [ 276, "14:02:38.525962", 2, 0,
"calc.str(\"L11\");" ]
[1] [ 277, "14:02:38.525962", 2, 18,
"calc.str(\"L11\");" ]
[1] [ 278, "14:02:38.526000", 2, 0,
"calc.str(\"f_trigger\");" ]
[1] [ 279, "14:02:38.526000", 2, 18,
"calc.str(\"f_trigger\");" ]
[1] [ 280, "14:02:38.526039", 2, 0,
"calc.str(\"machine_uuid\");" ]
[1] [ 281, "14:02:38.526039", 2, 19,
"calc.str(\"machine_uuid\");" ]
[1] [ 282, "14:02:38.526077", 2, 0,
"calc.str(\"f_trigger\");" ]
[1] [ 283, "14:02:38.526077", 2, 20,
"calc.str(\"f_trigger\");" ]
[1] [ 284, "14:02:38.526116", 2, 0,
"calc.str(nil:str);" ]
[1] [ 285, "14:02:38.526116", 2, 22,
"calc.str(nil:str);" ]
[1] [ 286, "14:02:38.528707", 2, 0, "X_21 :=
nil:bat[:oid,:str];" ]
[1] [ 287, "14:02:38.528707", 2, 64, "X_21 :=
nil:bat[:oid,:str];" ]
[1] [ 288, "14:02:38.528790", 2, 0,
"X_39:bat[:oid,:wrd] := nil:bat[:oid,:wrd];" ]
[1] [ 289, "14:02:38.528790", 2, 27,
"X_39:bat[:oid,:wrd] := nil:bat[:oid,:wrd];" ]
[1] [ 290, "14:02:38.528835", 2, 0, "barrier X_596 :=
language.dataflow();" ]
[1] [ 291, "14:02:38.528928", 40, 0, "X_2 := sql.mvc();"
]
[1] [ 292, "14:02:38.528928", 40, 141, "X_2 := sql.mvc();"
]
[1] [ 293, "14:02:38.529100", 40, 0,
"X_12:bat[:oid,:str] :=
sql.bind(X_2=0,\"sys\",\"f_trigger\",\"script_id\",0);" ]
[1] [ 294, "14:02:38.529100", 40, 78,
"X_12:bat[:oid,:str] =