Skip to content

sqlx fetch_all for huge amount of data much slower then tokio-postgres #2007

Open
@dragonnn

Description

@dragonnn

I recently started using sqlx for querying huge amount of data, about 12096001 rows x 6 columns. That is running on postgresql with timescaledb on top of it. Those are 0.1s samples for two weeks for vibration sensors.

Running EXPLAIN ANALYZE on my query did show much lower query time that I was getting in my program using sqlx. So I decided to test out tokio-postgres.
I found out that tokio-postgres is almost 50% faster then sqlx with mapping tokio-postgres Row type to the same struct sqlx is querying to. Exact numbers:

tokio_postgres_query_time: 9386ms
tokio_postgres_query_time with map: 13028ms
sqlx_query_time query_as: 29830ms
sqlx_query_time query: 29205ms

with map is with maping tokio-postgres output to my struct, still much faster.
This is with tokio-postgres running the query first, sqlx second, so the db might cache something already for sqlx?
I know sqlx doesn't focus on performance, but I always assumed that is mostly about throughput for running multiple queries fast, not for a single fetch_all query. I also tested without using query_as but the times are almost the same, so the bottleneck isn't in mapping structs.
My Rust struct:

#[derive(FromRow, Encode, Debug, Serialize, Deserialize, PartialEq, Clone, pg_mapper::TryFromRow)]
pub struct Data {
    pub datetime: chrono::NaiveDateTime,
    pub measuring_result: f64,
    pub alert_alarm: bool,
    pub danger_alarm: bool,
    pub work_state_id: Option<i32>,
    pub device_uuid: Uuid,
}

My table:

CREATE TABLE vibrodetectors.data (
	datetime timestamp NOT NULL,
	measuring_result double precision NOT NULL,
	alert_alarm bool NOT NULL,
	danger_alarm bool NOT NULL,
	device_uuid uuid NOT NULL,
	work_state_id integer,
	CONSTRAINT data_pk PRIMARY KEY (datetime,device_uuid)

);

And the query itself:

SELECT * FROM vibrodetectors.data WHERE device_uuid = ($1) AND (datetime >= $2 AND ($3 OR datetime <= $4)) ORDER BY datetime ASC

I don't think I need to paste the rust code itself, but I do have plans to take the code out of my project and create a minimum viable example for testing and getting some flamegraphs. For now I unfortunately need to ingrate tokio-postgres into my project and use it for getting the huge data out of the db.
This was all done under sqlx 6.0 and tokio-postgres 0.7.6

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions