Hi hackers,

While I was reviewing some code in another patch, I stumbled upon a possible 
optimization in the btree index code in nbtsearch.c for queries using 'LIMIT 
1'. I have written a small patch that implements this optimization, but I'd 
like some feedback on the design of the patch, whether it is correct at all to 
use this optimization, and whether the performance tradeoffs are deemed worth 
it by the community.


Basically, an example of the case I'd like to optimize is the following. Given 
a table 'tbl' with an index on columns (k,ts DESC):


SELECT* FROM tbl WHERE k=:val AND ts<=:timestamp ORDER BY k, ts DESC LIMIT 1;


And, even more importantly, when this query gets called in an inner loop like:


SELECT* FROM generate_series(:start_ts, :end_ts, :interval) ts -- perhaps 
thousands of iterations, could also be a loop over values of 'k' rather than 
timestamps. this is just an example

CROSS JOIN LATERAL (

   SELECT* FROM tbl WHERE k=:val AND ts<=:timestamp ORDER BY k, ts DESC LIMIT 1;

) _;


With time-series data, this case often arises as you have a certain natural key 
for which you store updates as they occur. Getting the state of k at a specific 
time then boils down to the given query there, which is almost always the 
fastest way to get this information, since the index scan with LIMIT 1 is very 
fast already. However, there seems to be a possibility to make this even faster 
(up to nearly 3x faster in test cases that use this nested loop of index scans)

Every time the index scan is done, all tuples from the leaf page are read in 
nbtsearch.c:_bt_readpage. The idea of this patch is to make an exception for 
this *only* the first time amgettuple gets called. This calls _bt_first in 
nbtsearch.c, which will, if there are scankeys, descend the tree to a leaf page 
and read just the first (or possibly two) tuples. It won't touch the rest of 
the page yet. If indeed just one tuple was required, there won't be a call to 
_bt_next and we're done. If we do need more than one tuple, _bt_next will 
resume reading tuples from the index page at the point where we left off.


There are a few caveats:

- Possible performance decrease for queries that need a small number of tuples 
(but more than one), because they now need to lock the same page twice. This 
can happen in several cases, for example: LIMIT 3; LIMIT 1 but the first tuple 
returned does not match other scan conditions; LIMIT 1 but the tuple returned 
is not visible; no LIMIT at all but there are just only a few matching rows.

- We need to take into account page splits, insertions and vacuums while we do 
not have the read-lock in between _bt_first and the first call to _bt_next. 
This made my patch quite a bit more complicated than my initial implementation.


I did performance tests for some best case and worst case test scenarios. TPS 
results were stable and reproducible in re-runs on my, otherwise idle, server. 
Attached are the full results and how to reproduce. I picked test cases that 
show best performance as well as worst performance compared to master. Summary: 
the greatest performance improvement can be seen for the cases with the 
subquery in a nested loop. In a nested loop of 100 times, the performance is 
roughly two times better, for 10000 times the performance is roughly three 
times better. For most test cases that don't use LIMIT 1, I couldn't find a 
noticeable difference, except for the nested loop with a LIMIT 3 (or similarly, 
a nested loop without any LIMIT-clause that returns just three tuples). This is 
also theoretically the worst-case test case, because it has to lock the page 
again and then read it, just for one tuple. In this case, I saw TPS decrease by 
2-3% in a few cases (details in the attached file), due to it having to 
lock/unlock the same page in both _bt_first and _bt_next.


A few concrete questions to the community:

- Does the community also see this as a useful optimization?

- Is the way it is currently implemented safe? I struggled quite a bit to get 
everything working with respect to page splits and insertions. In particular, I 
don't know why in my patch, _bt_find_offset_for_tid needs to consider searching 
for items with an offset *before* the passed offset. As far as my understanding 
goes, this could only happen when the index gets vacuumed in the mean-time. 
However, we hold a pin on the buffer the whole time (we even assert this), so 
vacuum should not have been possible. Still, this code gets triggered 
sometimes, so it seems to be necessary. Perhaps someone in the community who's 
more of an expert on this can shed some light on it.

- What are considered acceptable performance tradeoffs in this case? Is a 
performance degradation in any part generally not acceptable at all?


I'd also welcome any feedback on the process - this is my first patch and while 
I tried to follow the guidelines, I may have missed something along the way.


Attachments:

- out_limit.txt: pgbench results for patched branch

- out_master.txt pgbench results for master branch (can be diffed with 
out_limit.txt to efficiently see the difference)

- init_test.sql: creates a simple table for the test cases and fills it with 
data

- test_fwd.sql: the nested loop example, parameters :nlimit and :nitems to 
specify how many rows per inner loop to limit to and how many iterations of the 
loop need to be done. we're returning a sum() over a column to make sure 
transferring result data over the socket is not the bottleneck - this is to 
show the worst-case behavior of this patch. When selecting the full row instead 
of the sum, the performance difference is negligible for the 'bad' cases, while 
still providing great (up to 2.5x) improvements for the 'good' cases. This can 
be tested by changing the sum() to select a column per row instead.

- test_fwd_eq.sql: nested loop with simple unique equality select

- test_fwd_single.sql: single query with LIMIT without nested loop


-Floris

Attachment: 0001-Optimize-single-tuple-fetch-from-nbtree-index-v01.patch
Description: 0001-Optimize-single-tuple-fetch-from-nbtree-index-v01.patch

Attachment: init_test.sql
Description: init_test.sql

+++++ dirname ./test_limit.sh
++++ cd .
++++ pwd
+++ DIR=/home/florisvannee/workspace/pg_dev/limit
+++ T=20
+++ /home/florisvannee/workspace/pg_dev/start.sh
++++ [[ 0 -eq 2 ]]
++++ [[ 0 -eq 1 ]]
++++ bdir=/home/florisvannee/workspace/postgres
++++ cd /home/florisvannee/workspace/postgres
+++++ git rev-parse --abbrev-ref HEAD
++++ totaldir=limit-release
++++ /home/florisvannee/install/limit-release/bin/pg_ctl 
-D/home/florisvannee/pgdata/limit-release -l 
/home/florisvannee/pgdata/limit-release/logfile -t 5 stop
pg_ctl: could not send stop signal (PID: 28145): No such process
++++ pkill -9 postgres
++++ /home/florisvannee/install/limit-release/bin/pg_ctl 
-D/home/florisvannee/pgdata/limit-release -l 
/home/florisvannee/pgdata/limit-release/logfile start
pg_ctl: another server might be running; trying to start server anyway
waiting for server to start.... done
server started
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd_eq.sql -T 
20 postgres -Dnitems=1
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd_eq.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 156764
latency average = 0.128 ms
tps = 7838.184195 (including connections establishing)
tps = 7839.331599 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd_eq.sql -T 
20 postgres -Dnitems=10
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd_eq.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 131079
latency average = 0.153 ms
tps = 6553.920794 (including connections establishing)
tps = 6554.874046 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd_eq.sql -T 
20 postgres -Dnitems=100
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd_eq.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 50692
latency average = 0.395 ms
tps = 2534.595231 (including connections establishing)
tps = 2534.967502 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd_eq.sql -T 
20 postgres -Dnitems=1000
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd_eq.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 7621
latency average = 2.624 ms
tps = 381.043284 (including connections establishing)
tps = 381.093124 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd_single.sql 
-T 20 postgres -Dnlimit=1
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd_single.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 229991
latency average = 0.087 ms
tps = 11499.514293 (including connections establishing)
tps = 11501.125904 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd_single.sql 
-T 20 postgres -Dnlimit=3
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd_single.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 215881
latency average = 0.093 ms
tps = 10794.011481 (including connections establishing)
tps = 10794.899742 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd_single.sql 
-T 20 postgres -Dnlimit=50
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd_single.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 173334
latency average = 0.115 ms
tps = 8666.645542 (including connections establishing)
tps = 8667.882794 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=10 -Dnlimit=1
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 117364
latency average = 0.170 ms
tps = 5868.162298 (including connections establishing)
tps = 5868.966227 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=100 -Dnlimit=1
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 49578
latency average = 0.403 ms
tps = 2478.893661 (including connections establishing)
tps = 2479.258209 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=1000 -Dnlimit=1
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 7897
latency average = 2.533 ms
tps = 394.817306 (including connections establishing)
tps = 394.874583 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=10000 -Dnlimit=1
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 842
latency average = 23.775 ms
tps = 42.060903 (including connections establishing)
tps = 42.066652 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=10 -Dnlimit=3
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 91328
latency average = 0.219 ms
tps = 4566.376538 (including connections establishing)
tps = 4566.973889 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=100 -Dnlimit=3
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 21644
latency average = 0.924 ms
tps = 1082.149192 (including connections establishing)
tps = 1082.288793 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=1000 -Dnlimit=3
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 2575
latency average = 7.769 ms
tps = 128.715772 (including connections establishing)
tps = 128.734108 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=10000 -Dnlimit=3
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 263
latency average = 76.250 ms
tps = 13.114679 (including connections establishing)
tps = 13.116601 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=10 -Dnlimit=50
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 55591
latency average = 0.360 ms
tps = 2779.537585 (including connections establishing)
tps = 2779.926201 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=100 -Dnlimit=50
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 9465
latency average = 2.113 ms
tps = 473.205818 (including connections establishing)
tps = 473.274649 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=1000 -Dnlimit=50
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 1015
latency average = 19.709 ms
tps = 50.738310 (including connections establishing)
tps = 50.745497 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=10000 -Dnlimit=50
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 103
latency average = 194.247 ms
tps = 5.148077 (including connections establishing)
tps = 5.148805 (excluding connections establishing)
+++++ dirname ./test_limit.sh
++++ cd .
++++ pwd
+++ DIR=/home/florisvannee/workspace/pg_dev/limit
+++ T=20
+++ /home/florisvannee/workspace/pg_dev/start.sh master
++++ [[ 1 -eq 2 ]]
++++ [[ 1 -eq 1 ]]
++++ bdir=/home/florisvannee/workspace/postgres
++++ totaldir=master-release
++++ cd /home/florisvannee/workspace/postgres
++++ /home/florisvannee/install/master-release/bin/pg_ctl 
-D/home/florisvannee/pgdata/master-release -l 
/home/florisvannee/pgdata/master-release/logfile -t 5 stop
pg_ctl: could not send stop signal (PID: 29950): No such process
++++ pkill -9 postgres
++++ /home/florisvannee/install/master-release/bin/pg_ctl 
-D/home/florisvannee/pgdata/master-release -l 
/home/florisvannee/pgdata/master-release/logfile start
pg_ctl: another server might be running; trying to start server anyway
waiting for server to start.... done
server started
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd_eq.sql -T 
20 postgres -Dnitems=1
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd_eq.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 154896
latency average = 0.129 ms
tps = 7744.777852 (including connections establishing)
tps = 7745.481275 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd_eq.sql -T 
20 postgres -Dnitems=10
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd_eq.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 130189
latency average = 0.154 ms
tps = 6509.413300 (including connections establishing)
tps = 6510.194847 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd_eq.sql -T 
20 postgres -Dnitems=100
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd_eq.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 51467
latency average = 0.389 ms
tps = 2573.330950 (including connections establishing)
tps = 2573.706453 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd_eq.sql -T 
20 postgres -Dnitems=1000
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd_eq.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 7820
latency average = 2.558 ms
tps = 390.956588 (including connections establishing)
tps = 391.013884 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd_single.sql 
-T 20 postgres -Dnlimit=1
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd_single.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 219722
latency average = 0.091 ms
tps = 10986.053856 (including connections establishing)
tps = 10987.598953 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd_single.sql 
-T 20 postgres -Dnlimit=3
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd_single.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 215711
latency average = 0.093 ms
tps = 10785.486753 (including connections establishing)
tps = 10786.586186 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd_single.sql 
-T 20 postgres -Dnlimit=50
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd_single.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 174473
latency average = 0.115 ms
tps = 8723.607124 (including connections establishing)
tps = 8724.854159 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=10 -Dnlimit=1
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 93067
latency average = 0.215 ms
tps = 4653.322050 (including connections establishing)
tps = 4654.022097 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=100 -Dnlimit=1
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 23328
latency average = 0.857 ms
tps = 1166.383516 (including connections establishing)
tps = 1166.560584 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=1000 -Dnlimit=1
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 2823
latency average = 7.086 ms
tps = 141.115678 (including connections establishing)
tps = 141.135409 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=10000 -Dnlimit=1
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 292
latency average = 68.710 ms
tps = 14.553922 (including connections establishing)
tps = 14.555983 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=10 -Dnlimit=3
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 90974
latency average = 0.220 ms
tps = 4548.655001 (including connections establishing)
tps = 4549.337781 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=100 -Dnlimit=3
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 22080
latency average = 0.906 ms
tps = 1103.982784 (including connections establishing)
tps = 1104.122082 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=1000 -Dnlimit=3
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 2630
latency average = 7.606 ms
tps = 131.467656 (including connections establishing)
tps = 131.486783 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=10000 -Dnlimit=3
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 271
latency average = 73.890 ms
tps = 13.533643 (including connections establishing)
tps = 13.535616 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=10 -Dnlimit=50
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 56385
latency average = 0.355 ms
tps = 2819.202652 (including connections establishing)
tps = 2819.611918 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=100 -Dnlimit=50
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 9744
latency average = 2.053 ms
tps = 487.182328 (including connections establishing)
tps = 487.247681 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=1000 -Dnlimit=50
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 1050
latency average = 19.059 ms
tps = 52.469680 (including connections establishing)
tps = 52.477479 (excluding connections establishing)
+++ pgbench -n -f /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql -T 20 
postgres -Dnitems=10000 -Dnlimit=50
transaction type: /home/florisvannee/workspace/pg_dev/limit/test_fwd.sql
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 20 s
number of transactions actually processed: 107
latency average = 187.881 ms
tps = 5.322504 (including connections establishing)
tps = 5.323249 (excluding connections establishing)

Attachment: test_fwd.sql
Description: test_fwd.sql

Attachment: test_fwd_eq.sql
Description: test_fwd_eq.sql

Attachment: test_fwd_single.sql
Description: test_fwd_single.sql

Reply via email to