Closed SteveDirschelTR closed 9 months ago
You are trying to confuse me by talking about lob_prefetch
, which was introduced in 2.6.0. But oracle_diag()
shows that you are using version 2.5.0.
Before commit d679a73d02057fd674fc78fe5f25183e5c9a172b, oracle_fdw had a limitation that affected performance for LOBs. This is described in the README of version 2.5.0:
Note that due to an Oracle limitation, row prefetching won't work if the Oracle query involves a BLOB, CLOB or BFILE column. As a consequence, queries on such columns on a foreign table will perform badly if you fetch many rows.
The problem was that Oracle performed a client-server round trip for each table row fetched. That would also explain why the table with smaller LOBs seems to perform worse. If you count the time per table row, they are probably similar.
Use oracle_fdw version 2.6.0, that should improve the performance.
Hi,
I can confirm that oracle-fdw 2.6+ dramatically improves speed retrieval of lines that include CLOB/LOB columns. It's amazing to see it is now much faster to query an Oracle database from a PostgreSQL database than it is from another Oracle database (simple queries only of course !). It's even easier to query Oracle from PostgreSQL than to query Oracle directly in some cases. A LONG column is a TEXT in the foreign table. Hence you can use text (varchar) functions, something that is impossible directly from Oracle. Funny fact, Oracle knows it is a pain to manipulate LONG columns and they tried to add workarounds in their own dictionary.
Example with "all_constraints" view:
SEARCH_CONDITION LONG
SEARCH_CONDITION_VC VARCHAR2(4000)
You have 2 columns with the same information : a column that includes the complete information but it is difficult to query it OR a column that is easy to query but perhaps it is truncated. With oracle-fdw, search_condition is easy to query AND it is not truncated.
Use 2.6+ version if you do have LOB/CLOBS :) !!!!
Best regards, Phil
Something I didn't mention but Laurenz you had also observed that I think. oracle_fdw 2.6+ improves read performance of Oracle lines with lob/clob columns. But if you want to store those lines and to improve write speed at Postgres side it's also interesting to try lz4 instead of pglz for toast compression. I see "PostgreSQL 14.7" in the first post and the ability to choose lz4 for toast compression was added via default_toast_compression in this version. If PostgreSQL is compiled with --lz4 feature is available. Best regards, Phil
Are there any questions left?
No additional questions. Thanks
According to documentation:
lob_prefetch (optional, defaults to "1048576")
The size of the CLOB's I am copying are smaller than 1048576 so I have not changed lob_prefetch (below shows max bytes for the CLOB rows I'm copying is 40,657 bytes). I have set these 2 options for table co_session_binding:
ALTER FOREIGN TABLE uds_long_link.co_session_binding OPTIONS ( readonly 'off', prefetch '1000' );
This shows LOB info from the Oracle side for the rows I will test copy over.
Here I run the insert- 5m 24s
2020-11-06 data goes into the co_session_binding_created_time_20201107 partition
This shows the size of the partition on the Postgres side I just copied the data into. It is interesting that the table, index, toast is only 19.5 MB on the Postgres size when the CLOB data is 41.1 MB. There must be some compression going on.
Here is another table I am copying data for. The options for the table are the same as the other table. But this table does not have any CLOBS. Here is a test copy of 1 day of data- 2m 25s
ALTER FOREIGN TABLE uds_long_link.co_session OPTIONS ( readonly 'on', prefetch '1000' );
2020-12-24 data goes into the co_session_created_time_20201225 partition
So for table CO_SESSION (no CLOB) I can copy over 631 MB of table data in 2m 25s. But for CO_SESSION_BINDING (1 CLOB) it copied over 17 MB of table data + 2.2 MB of toast data = 19.2 MB in 5m 24s.
CO_SESSION = 4,563,113 bytes/second CO_SESSION_BINDING = 62,137 bytes/second
CO_SESSION is 73x faster than CO_SESSION_BINDING. I noted above that the LOB size is larger than the table/toast for this table so I'm not sure how to take that into account when calculating out bytes/second but CO_SESSION_BINDING is significantly slower no matter what numbers you use. What can be done to speed this up? At this pace we will not be able to keep up with copying data for this table- it will be generated at a faster pace than it can be copied (at least single threaded).
Table definitions in Oracle:
Let me know if you need additional details on this. Thanks