-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is everything in this request necessary (especially the DROP TABLE
)?
#45
Comments
The temp table is created to store the result of the query with sorting option and pagination. The secondary sort if supported server side, but the table QML component do not allow it natively. |
When looking at timing, the first block takes 2300 to 2400 ms (essentially the SELECT
ROW_NUMBER() OVER(ORDER BY chr) as page,
variant_id,
array_remove(array_agg(trx_pk_value), NULL) as trx,
count(trx_pk_value) as trx_count,
chr
FROM wt_7
WHERE (filter_1)
GROUP BY variant_id, chr; The following block (for display) takes 100 ms. SELECT ws.variant_id, wt.is_selected, ws.trx_count, wt.vcf_line, wt.chr, wt.pos, wt.ref, wt.alt, wt.s89_gt, wt.s90_gt, wt.s91_gt, wt.s89_dp, wt.s90_dp, wt.s91_dp, wt.s89_dp_alt, wt.s90_dp_alt, wt.s91_dp_alt, wt.s89_qual, wt.s90_qual, wt.s91_qual, wt.s89_filter, wt.s90_filter, wt.s91_filter, wt.regovar_score, wt._c226c0068ff542e6b96e8a547d343769, wt._5b6c898a867eb9246614fed7fd73ef2a, wt.sample_tcount, wt._db6645831e7c4e8122866831bb033cb1, wt._c34d543d6e41fed6c6f2b5880648e5ba, wt._fe8e0aa7569f01b555ea16a1dfb4cc95, wt._b5968c1a27a8955b5b64f83da60a4ecf, wt._5803633f01600a2e047aad3ee2faa133, wt._4a3364a3e728fba77ba24ac0139f11af, wt._8ce3587f7cf3983d5bcc9058a74a8d1e, wt._310648e1b6bb1030c44d63034ced7243, wt._4001d967fcb1d2153872eff7ba36cc2c, wt._518485ecbbcebd1f55c7350f8314e8bc, wt._8409cac61d602ba979a6856a0d7614d4
FROM wt_7_tmp ws
INNER JOIN wt_7 wt ON ws.variant_id=wt.variant_id
WHERE wt.is_variant AND ws.page>=0
ORDER BY ws.page
LIMIT 100; Could we avoid the creation of the table at each sorting or is it possible to optimize the times? |
$ sudo -u regovar psql -d regovar -c "EXPLAIN ANALYZE SELECT ROW_NUMBER() OVER(ORDER BY chr) as page, variant_id, array_remove(array_agg(trx_pk_value), NULL) as
trx, count(trx_pk_value) as trx_count, chr FROM wt_7 WHERE (filter_1) GROUP BY variant_id, chr;"
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------
WindowAgg (cost=565700.98..573219.04 rows=375903 width=60) (actual time=2051.588..2066.836 rows=29933 loops=1)
-> Sort (cost=565700.98..566640.74 rows=375903 width=52) (actual time=2051.401..2054.481 rows=29933 loops=1)
Sort Key: chr
Sort Method: external sort Disk: 3256kB
-> GroupAggregate (cost=489828.19..518043.87 rows=375903 width=52) (actual time=1993.938..2035.505 rows=29933 loops=1)
Group Key: variant_id, chr
-> Sort (cost=489828.19..494531.57 rows=1881351 width=26) (actual time=1993.922..2004.529 rows=102351 loops=1)
Sort Key: variant_id, chr
Sort Method: external merge Disk: 3184kB
-> Seq Scan on wt_7 (cost=0.00..203733.02 rows=1881351 width=26) (actual time=0.698..1943.727 rows=102351 loops=1)
Filter: filter_1
Rows Removed by Filter: 3660351
Planning time: 1.710 ms
Execution time: 2068.723 ms |
Time is spent scanning all 3.5M rows to filter using “filter_1” everytime the sort criterion is changed. What is “filter_1”, exactly? Could we use some index / cache there? |
Summary:
I guess (please correct me if I'm wrong) that the filtering step, responsible for ~95% of the runtime, does not yield different results when only the sort criterion changes, meaning that some caching would allow us to shave the runtime down to around 120ms (ie. ~200ms overall, accounting for the ~70ms of the subsequent Maybe doing the grouping / sorting stuff in the |
If you don't want to regenerate the wt_tmp table on sorting, that means that we don't save this information in the wt_tmp table, so the sorting must be done dynamically each time the client need to retrieve data. that also means that each time we have to first do a join with wt table to retrieve sorted column to then apply the sort and then the limit-offset (pagination) That will be quick when we have few rows, but it will be longer than the current solution when we have lot of rows... |
@Arkanosis: Do you know if it's possible to set PostgreSQL to create "In-Memory table" like in MySQL. I quickly searched and found that this feature could be done with PostgreSQL 10. I thinks that creating In-Memory table for wt_{id}_tmp table is the solution to optimize filtering. |
Dunno… Would it be to avoid I/Os? Because I'm actually not convinced we have an I/O issue here. There's so much RAM available on Brownie that everything is most likely in memory already (what I've seen when playing with the above query is that it was CPU-bound). See with a less CPU-intensive query:
(Obviously the client itself doesn't account for much of the runtime. Only a mere 60ms of CPU time). Not only there is zero major page fault (ie. actual disk read, CMAJFLT), but the ~1500 minor page faults (ie. mapping of data already in physical memory into the process virtual address space, CMINFLT) account for at most 340ms (CSTIME) of the CPU time (worst case where all of the system CPU time is spent handling minor page faults). |
The problem of performance occure when whe apply a filter, because I drop/create a temps table to hold the result. So the request to test is more something like this
I test this command like you, but I do not understand what i'm monitoring ...
Where do you see that we are bound by the CPU ? we only use 9% ? Are you sure that write access are monitored by this tool ? |
Yeah, but it's the
You're monitoring the client. It takes 6.9 seconds from the time you press enter to the moment you get your prompt back, uses the CPUs during 50ms to run the client code and 20ms to run the Linux kernel code. It makes no I/O (see major faults), yet accesses data that is not yet mapped in the client process' address space 2465 times (could have been as many I/Os, but data was already in RAM). The most important information you get here, is that the client is responsible for almost nothing time-wise. Most time is actually spent by the server processes, which you can monitor using htop. Substract CUTIME before the Here, for ~1mn of wall clock time measured at the client, we're spending ~1mn running pg's server processes on the CPUs. Assuming only one core is used (I'm pretty sure that's the case), this means pretty much all the time is spent waiting for the CPU. Also note that I've simplified the |
Ok thanks for the explanations. So my test with default pg server settings take 6 seconds. The remaining 3s are all spent in the sequencial scan of all entry of the table wt_7. For additional optimization, we have to change the "regovar workflow" and how/when data are processed. The sequential scan of all entries is done because I read all variants and their transcripts (only to know how many transcript match by variant to be able to display in the treeView the icon that indicates that the entry have sub-entries). But as the user don't need transcript's information in a first time (they work only at hight level with gene/variant and check transcripts only they found an interesting variant). We could assume that we display the icon for subentries in the treeview everytime, and then trying to retrieving variant's transcripts only when requested by the user... |
When Arkanosis did the test, he didn't have the same results: tuning postgresql's settings to use quicksort instead of external merge sort didn't result in any significant improvement in the Arkanosis tests (but it was only taking around 2 seconds overall). Nevertheless the nearly same tuning by Ikit ( |
I'm testing like you on Brownie with wt_7. But this table have been regenerated between Arkanosis test and mine (that's probably why few additionnal transcript have been found...). No big change since Feb 5th regarding data generation wt_:
Note also that planning/execution may differ a little between each execution the command:
I just run the command 5 times and it took between ~ 4900ms and 5400ms. |
Oh yes, that's probably it. You're sorting / grouping many more results than I was. |
Optimization
I want to sort data in the analysis table. Request is quite long. I look at the requests below.
First, sort on
SYMBOL
. It drops the table.Second, sort on
FILTER
. It drops the table even though it is almost the same.For reference, below is the request which is done in both cases after the creation of the table. It doesn't look like the result will be different.
Secondary sort
Is a secondary sort possible? For example, by first sorting on
chr
and then by sorting onposition
.The text was updated successfully, but these errors were encountered: