Benchw Results

The Servers

These are benchmark results for the following :

All were compiled from source using gcc 3.3.4. No special compiler flags were used for Postgres and Firebird - autoconf seemed to do a good enough job. For Mysql the recommended autoconf options for FreeBSD were used. A Firebird classic server was built.

Tuning parameters were set as detailed in the documentation for Benchw version 1.1 - i.e. 100M of buffers and 20M sort per process.

The default suggested indexes were used - i.e no time was spent trying to discover if some of the servers would perform better with differing index configurations.

Remember these are results particular to these versions of the servers, the hardware plus os they were run on, and are intended to be informational (maybe provoking some discussion) rather than a crusade about which product is the 'best one'.

The benchmark was performed on 23/08/2004 by markir@paradise.net.nz

Platform

Mobo/CPU/MemoryTyan Tiger 133 2xPIII 700Mhz 2G
IO2x40G 7200 RPM ATA-133 PROMISE TX2000 RAID 0
OSFreeBSD 4.10

Despite being an old machine, the well equipped memory and io subsystems meant it was quite suitable for this sort of activity.

Results

Both sets of results were for size = 1 (the default)

This first set of results consisted of a complete run of load, index and query. Note that some caching of data from the load and index stages effected the queries.

TestPostgresFirebirdMysql
Load401s1540s676s
Index643s524s0s
Query05s10s10s
Query13s9s10s
Query239s70s131s
Query336s77s89s
Query449s90s98s

This second run consisted of queries only, after a system restart to forceably clear all caches. Therefore caching effect derived purely from any repeated scanning of data visited in previous queries. Note that this was particularly noticeable for the second query - as it retrieved the same data as the first.

TestPostgresFirebirdMysql
Query025s32s29s
Query13s9s10s
Query252s137s196s
Query336s77s89s
Query449s221s224s

Notes

Appendix

The Tables

The schema used is reproduced below, it is a simple 'star' with 1 'fact' and 3 'dimensions', one of which is 'timelike'.

--
--  benchw schema : 
--

--  timelike dimension
--  cardinality = 10000
CREATE TABLE dim0 (
	d0key                          INTEGER NOT NULL,
	ddate                          DATE NOT NULL,
	dyr                            INTEGER NOT NULL,
	dmth                           INTEGER NOT NULL,
	dday                           INTEGER NOT NULL
);

--  dimension
--  cardinality = 10000
CREATE TABLE dim1 (
	d1key                          INTEGER NOT NULL,
	dat                            VARCHAR(100) NOT NULL,
	dattyp                         VARCHAR(20) NOT NULL,
	dfill                          VARCHAR(100) NOT NULL
);

--  dimension
--  cardinality = 10000
CREATE TABLE dim2 (
	d2key                          INTEGER NOT NULL,
	dat                            VARCHAR(100) NOT NULL,
	dattyp                         VARCHAR(20) NOT NULL,
	dfill                          VARCHAR(100) NOT NULL
);

--  fact
--  cardinality = 10000000
CREATE TABLE fact0 (
	d0key                          INTEGER NOT NULL,
	d1key                          INTEGER NOT NULL,
	d2key                          INTEGER NOT NULL,
	fval                           INTEGER NOT NULL,
	ffill                          VARCHAR(100) NOT NULL
);


--
--  benchw (suggested) indexes :
--
CREATE UNIQUE INDEX dim0_d0key ON dim0(d0key)
;

CREATE UNIQUE INDEX dim1_d1key ON dim1(d1key)
;

CREATE UNIQUE INDEX dim2_d2key ON dim2(d2key)
;

CREATE INDEX fact0_d0key ON fact0(d0key)
;

CREATE INDEX fact0_d1key ON fact0(d1key)
;

CREATE INDEX fact0_d2key ON fact0(d2key)
;

      

The Queries

The queries are reproduced below. Note that for Firebird these were generated without the AS qualifier in the FROM clause.

--
--  benchw query : generated by querygen
--               : query type 0
--
SELECT 
	d0.dmth,
	count(f.fval )
FROM
	dim0 AS d0,
	fact0 AS f
WHERE 	d0.d0key = f.d0key
AND 	d0.ddate BETWEEN '2010-01-01' AND '2010-12-28'
GROUP BY
	d0.dmth
;
--
--  benchw query : generated by querygen
--               : query type 1
--
SELECT 
	d0.dmth,
	count(f.fval )
FROM
	dim0 AS d0,
	fact0 AS f
WHERE 	d0.d0key = f.d0key
AND 	d0.dyr = 2010
GROUP BY
	d0.dmth
;
--
--  benchw query : generated by querygen
--               : query type 2
--
SELECT 
	d0.dmth,
	d1.dat,
	count(f.fval )
FROM
	dim0 AS d0,
	dim1 AS d1,
	fact0 AS f
WHERE 	d0.d0key = f.d0key
AND 	d1.d1key = f.d1key
AND 	d0.dyr BETWEEN 2010 AND 2015
AND 	d1.dattyp BETWEEN '10th measure type' AND '14th measure type'
GROUP BY
	d0.dmth,
	d1.dat
;
--
--  benchw query : generated by querygen
--               : query type 3
--
SELECT 
	d0.dmth,
	d1.dat,
	d2.dat,
	count(f.fval )
FROM
	dim0 AS d0,
	dim1 AS d1,
	dim2 AS d2,
	fact0 AS f
WHERE 	d0.d0key = f.d0key
AND 	d1.d1key = f.d1key
AND 	d2.d2key = f.d2key
AND 	d0.dyr BETWEEN 2010 AND 2015
AND 	d1.dattyp BETWEEN '10th measure type' AND '14th measure type'
AND 	d2.dattyp BETWEEN '1th measure type' AND '4th measure type'
GROUP BY
	d0.dmth,
	d1.dat,
	d2.dat
;
--
--  benchw query : generated by querygen
--               : query type 4
--
SELECT 
	d0.dyr,
	count(f.fval )
FROM
	dim0 AS d0,
	fact0 AS f
WHERE 	d0.d0key = f.d0key
AND 	d0.dyr < 2010
GROUP BY
	d0.dyr
;
      

Query Plans - Postgres



Query 0
-------

                                         QUERY PLAN                                         
--------------------------------------------------------------------------------------------
 HashAggregate  (cost=286953.94..286953.94 rows=1 width=8)
   ->  Nested Loop  (cost=0.00..285268.93 rows=337002 width=8)
         ->  Seq Scan on dim0 d0  (cost=0.00..219.00 rows=337 width=8)
               Filter: ((ddate >= '2010-01-01'::date) AND (ddate <= '2010-12-28'::date))
         ->  Index Scan using fact0_d0key on fact0 f  (cost=0.00..833.07 rows=1022 width=8)
               Index Cond: ("outer".d0key = f.d0key)
(6 rows)

Query 1
-------

                                         QUERY PLAN                                         
--------------------------------------------------------------------------------------------
 HashAggregate  (cost=284376.40..284376.40 rows=1 width=8)
   ->  Nested Loop  (cost=0.00..282706.39 rows=334002 width=8)
         ->  Seq Scan on dim0 d0  (cost=0.00..194.00 rows=334 width=8)
               Filter: (dyr = 2010)
         ->  Index Scan using fact0_d0key on fact0 f  (cost=0.00..833.07 rows=1022 width=8)
               Index Cond: ("outer".d0key = f.d0key)
(6 rows)

Query 2
-------

                                                             QUERY PLAN                                                              
-------------------------------------------------------------------------------------------------------------------------------------
 HashAggregate  (cost=341776.65..341777.42 rows=311 width=37)
   ->  Hash Join  (cost=618.13..341582.54 rows=25880 width=37)
         Hash Cond: ("outer".d0key = "inner".d0key)
         ->  Hash Join  (cost=394.34..340424.95 rows=135001 width=37)
               Hash Cond: ("outer".d1key = "inner".d1key)
               ->  Seq Scan on fact0 f  (cost=0.00..288680.40 rows=10000040 width=12)
               ->  Hash  (cost=394.00..394.00 rows=135 width=33)
                     ->  Seq Scan on dim1 d1  (cost=0.00..394.00 rows=135 width=33)
                           Filter: (((dattyp)::text >= '10th measure type'::text) AND ((dattyp)::text <= '14th measure type'::text))
         ->  Hash  (cost=219.00..219.00 rows=1917 width=8)
               ->  Seq Scan on dim0 d0  (cost=0.00..219.00 rows=1917 width=8)
                     Filter: ((dyr >= 2010) AND (dyr <= 2015))
(12 rows)

Query 3
-------

                                                                QUERY PLAN                                                                 
-------------------------------------------------------------------------------------------------------------------------------------------
 HashAggregate  (cost=342382.53..342415.51 rows=13192 width=66)
   ->  Hash Join  (cost=1024.87..342250.61 rows=13192 width=66)
         Hash Cond: ("outer".d2key = "inner".d2key)
         ->  Hash Join  (cost=618.13..341582.54 rows=25880 width=41)
               Hash Cond: ("outer".d0key = "inner".d0key)
               ->  Hash Join  (cost=394.34..340424.95 rows=135001 width=41)
                     Hash Cond: ("outer".d1key = "inner".d1key)
                     ->  Seq Scan on fact0 f  (cost=0.00..288680.40 rows=10000040 width=16)
                     ->  Hash  (cost=394.00..394.00 rows=135 width=33)
                           ->  Seq Scan on dim1 d1  (cost=0.00..394.00 rows=135 width=33)
                                 Filter: (((dattyp)::text >= '10th measure type'::text) AND ((dattyp)::text <= '14th measure type'::text))
               ->  Hash  (cost=219.00..219.00 rows=1917 width=8)
                     ->  Seq Scan on dim0 d0  (cost=0.00..219.00 rows=1917 width=8)
                           Filter: ((dyr >= 2010) AND (dyr <= 2015))
         ->  Hash  (cost=394.00..394.00 rows=5097 width=33)
               ->  Seq Scan on dim2 d2  (cost=0.00..394.00 rows=5097 width=33)
                     Filter: (((dattyp)::text >= '1th measure type'::text) AND ((dattyp)::text <= '4th measure type'::text))
(17 rows)

Query 4
-------

                                  QUERY PLAN                                   
-------------------------------------------------------------------------------
 HashAggregate  (cost=388893.14..388893.17 rows=11 width=8)
   ->  Hash Join  (cost=202.34..372223.08 rows=3334014 width=8)
         Hash Cond: ("outer".d0key = "inner".d0key)
         ->  Seq Scan on fact0 f  (cost=0.00..288680.40 rows=10000040 width=8)
         ->  Hash  (cost=194.00..194.00 rows=3334 width=8)
               ->  Seq Scan on dim0 d0  (cost=0.00..194.00 rows=3334 width=8)
                     Filter: (dyr < 2010)
(7 rows)


      

Query Plans - Firebird



Query 0
-------

PLAN SORT (JOIN (D0 NATURAL,F INDEX (FACT0_D0KEY)))

Query 1
-------

PLAN SORT (JOIN (D0 NATURAL,F INDEX (FACT0_D0KEY)))

Query 2
-------

PLAN SORT (JOIN (D0 NATURAL,F INDEX (FACT0_D0KEY),D1 INDEX (DIM1_D1KEY)))

Query 3
-------

PLAN SORT (JOIN (D0 NATURAL,F INDEX (FACT0_D0KEY),D2 INDEX (DIM2_D2KEY),D1 INDEX (DIM1_D1KEY)))

Query 4
-------

PLAN SORT (JOIN (D0 NATURAL,F INDEX (FACT0_D0KEY)))


      

Query Plans - Mysql


+---------+
| Query 0 |
+---------+
| Query 0 |
+---------+
+----+-------------+-------+------+---------------+-------------+---------+-----------------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key         | key_len | ref             | rows  | Extra                                        |
+----+-------------+-------+------+---------------+-------------+---------+-----------------+-------+----------------------------------------------+
|  1 | SIMPLE      | d0    | ALL  | dim0_d0key    | NULL        | NULL    | NULL            | 10000 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | f     | ref  | fact0_d0key   | fact0_d0key | 4       | benchw.d0.d0key |  1000 |                                              |
+----+-------------+-------+------+---------------+-------------+---------+-----------------+-------+----------------------------------------------+
+---------+
| Query 1 |
+---------+
| Query 1 |
+---------+
+----+-------------+-------+------+---------------+-------------+---------+-----------------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key         | key_len | ref             | rows  | Extra                                        |
+----+-------------+-------+------+---------------+-------------+---------+-----------------+-------+----------------------------------------------+
|  1 | SIMPLE      | d0    | ALL  | dim0_d0key    | NULL        | NULL    | NULL            | 10000 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | f     | ref  | fact0_d0key   | fact0_d0key | 4       | benchw.d0.d0key |  1000 |                                              |
+----+-------------+-------+------+---------------+-------------+---------+-----------------+-------+----------------------------------------------+
+---------+
| Query 2 |
+---------+
| Query 2 |
+---------+
+----+-------------+-------+--------+-------------------------+-------------+---------+-----------------+-------+----------------------------------------------+
| id | select_type | table | type   | possible_keys           | key         | key_len | ref             | rows  | Extra                                        |
+----+-------------+-------+--------+-------------------------+-------------+---------+-----------------+-------+----------------------------------------------+
|  1 | SIMPLE      | d0    | ALL    | dim0_d0key              | NULL        | NULL    | NULL            | 10000 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | f     | ref    | fact0_d0key,fact0_d1key | fact0_d0key | 4       | benchw.d0.d0key |  1000 |                                              |
|  1 | SIMPLE      | d1    | eq_ref | dim1_d1key              | dim1_d1key  | 4       | benchw.f.d1key  |     1 | Using where                                  |
+----+-------------+-------+--------+-------------------------+-------------+---------+-----------------+-------+----------------------------------------------+
+---------+
| Query 3 |
+---------+
| Query 3 |
+---------+
+----+-------------+-------+--------+-------------------------------------+-------------+---------+-----------------+-------+----------------------------------------------+
| id | select_type | table | type   | possible_keys                       | key         | key_len | ref             | rows  | Extra                                        |
+----+-------------+-------+--------+-------------------------------------+-------------+---------+-----------------+-------+----------------------------------------------+
|  1 | SIMPLE      | d0    | ALL    | dim0_d0key                          | NULL        | NULL    | NULL            | 10000 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | f     | ref    | fact0_d0key,fact0_d1key,fact0_d2key | fact0_d0key | 4       | benchw.d0.d0key |  1000 |                                              |
|  1 | SIMPLE      | d2    | eq_ref | dim2_d2key                          | dim2_d2key  | 4       | benchw.f.d2key  |     1 | Using where                                  |
|  1 | SIMPLE      | d1    | eq_ref | dim1_d1key                          | dim1_d1key  | 4       | benchw.f.d1key  |     1 | Using where                                  |
+----+-------------+-------+--------+-------------------------------------+-------------+---------+-----------------+-------+----------------------------------------------+
+---------+
| Query 4 |
+---------+
| Query 4 |
+---------+
+----+-------------+-------+------+---------------+-------------+---------+-----------------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key         | key_len | ref             | rows  | Extra                                        |
+----+-------------+-------+------+---------------+-------------+---------+-----------------+-------+----------------------------------------------+
|  1 | SIMPLE      | d0    | ALL  | dim0_d0key    | NULL        | NULL    | NULL            | 10000 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | f     | ref  | fact0_d0key   | fact0_d0key | 4       | benchw.d0.d0key |  1000 |                                              |
+----+-------------+-------+------+---------------+-------------+---------+-----------------+-------+----------------------------------------------+

      

Valid HTML 4.01!