Documentation improvements.

This commit is contained in:
Anthony Tuininga 2020-09-03 15:03:38 -06:00
parent a21e06a60c
commit b4443c0f9f
2 changed files with 91 additions and 86 deletions

View File

@ -9,9 +9,8 @@ Overview
To use cx_Oracle 8 with Python and Oracle Database you need: To use cx_Oracle 8 with Python and Oracle Database you need:
- Python 3.5 and higher. Older versions of cx_Oracle may work with older - Python 3.5 and higher. Older versions of cx_Oracle may work with older
versions of Python, for example see :ref:`Installing cx_Oracle in Python 2 versions of Python.
<python2>`
- Oracle Client libraries. These can be from the free `Oracle Instant - Oracle Client libraries. These can be from the free `Oracle Instant
Client Client
@ -40,8 +39,8 @@ Quick Start cx_Oracle Installation
- Install `Python <https://www.python.org/downloads>`__ 3, if not already - Install `Python <https://www.python.org/downloads>`__ 3, if not already
available. On macOS you must always install your own Python. available. On macOS you must always install your own Python.
Python 3.5 and higher are supported by cx_Oracle 8. For Python 2, see Python 3.5 and higher are supported by cx_Oracle 8. If you use Python 2,
:ref:`Installing cx_Oracle in Python 2 <python2>`. then the older cx_Oracle 7.3 will install.
- Install cx_Oracle from `PyPI - Install cx_Oracle from `PyPI
<https://pypi.org/project/cx-Oracle/>`__ with: <https://pypi.org/project/cx-Oracle/>`__ with:
@ -794,12 +793,13 @@ If you are upgrading from cx_Oracle 5 note these installation changes:
Installing cx_Oracle in Python 2 Installing cx_Oracle in Python 2
================================ ================================
To install cx_Oracle in Python 2, use a command like:: cx_Oracle 7.3 was the last version with support for Python 2.
If you install cx_Oracle in Python 2 using the commands provided above, then
cx_Oracle 7.3 will be installed. This is equivalent to using a command like::
python -m pip install cx_Oracle==7.3 --upgrade --user python -m pip install cx_Oracle==7.3 --upgrade --user
cx_Oracle 7.3 was the last version with support for Python 2.
For other installation options such as installing through a proxy, see For other installation options such as installing through a proxy, see
instructions above. Make sure the Oracle Client libraries are in the system instructions above. Make sure the Oracle Client libraries are in the system
library search path because cx_Oracle 7 does not support the library search path because cx_Oracle 7 does not support the

View File

@ -91,61 +91,8 @@ already buffered in the Oracle Client libraries. Reducing round-trips helps
performance and scalability. An overhead of prefetching is the need for an performance and scalability. An overhead of prefetching is the need for an
additional data copy from Oracle Client's prefetch buffers. additional data copy from Oracle Client's prefetch buffers.
To tune queries that return an unknown number of rows, estimate the number of Choosing values for ``arraysize`` and ``prefetchrows``
rows returned and start with an appropriate :attr:`Cursor.arraysize` value. The ++++++++++++++++++++++++++++++++++++++++++++++++++++++
default is 100. Then set :attr:`Cursor.prefetchrows` to the ``arraysize``
value. Do not make the sizes unnecessarily large. Keep ``arraysize`` as big,
or bigger than, ``prefetchrows``. Adjust the values as needed for performance,
memory and round-trip usage. An example is:
.. code-block:: python
cur = connection.cursor()
cur.prefetchrows = 1000
cur.arraysize = 1000
for row in cur.execute("SELECT * FROM very_big_table"):
print(row)
For a large quantity of rows or very "wide" rows on fast networks you may prefer
to leave ``prefetchrows`` at its default value of 2. The documentation in
:ref:`roundtrips` shows how to measure round-trips.
If you are fetching a fixed number of rows, start your tuning by setting
``arraysize`` to the number of expected rows, and set ``prefetchrows`` to one
greater than this value. (Adding one removes the need for a round-trip to check
for end-of-fetch). For example, if you are querying 20 rows, perhaps to
:ref:`display a page <rowlimit>` of data, set ``prefetchrows`` to 21 and
``arraysize`` to 20:
.. code-block:: python
cur = connection.cursor()
cur.prefetchrows = 21
cur.arraysize = 20
for row in cur.execute("""
SELECT last_name
FROM employees
ORDER BY last_name
OFFSET 0 ROWS FETCH NEXT 20 ROWS ONLY"""):
print(row)
This will return all rows for the query in one round-trip.
If you know that a query returns just one row then set :attr:`Cursor.arraysize`
to 1 to minimize memory usage. The default prefetch value of 2 allows minimal
round-trips for single-row queries:
.. code-block:: python
cur = connection.cursor()
cur.arraysize = 1
cur.execute("select * from MyTable where id = 1"):
row = cur.fetchone()
print(row)
The best :attr:`Cursor.arraysize` and :attr:`Cursor.prefetchrows` values can be The best :attr:`Cursor.arraysize` and :attr:`Cursor.prefetchrows` values can be
found by experimenting with your application under the expected load of normal found by experimenting with your application under the expected load of normal
@ -153,31 +100,65 @@ application use. This is because the cost of the extra memory copy from the
prefetch buffers when fetching a large quantity of rows or very "wide" rows may prefetch buffers when fetching a large quantity of rows or very "wide" rows may
outweigh the cost of a round-trip for a single cx_Oracle user on a fast network. outweigh the cost of a round-trip for a single cx_Oracle user on a fast network.
However under production application load, the reduction of round-trips may help However under production application load, the reduction of round-trips may help
performance and overall system scalability. performance and overall system scalability. The documentation in
:ref:`round-trips <roundtrips>` shows how to measure round-trips.
Prefetching can also be enabled in an external :ref:`oraaccess.xml Here are some suggestions for the starting point to begin your tuning:
<optclientfiles>` file, which may be useful for tuning an application when
modifying its code is not feasible. Setting the size in ``oraaccess.xml`` will
affect the whole application, so it should not be the first tuning choice.
One place where increasing ``arraysize`` is particularly useful is in copying * To tune queries that return an unknown number of rows, estimate the number of
data from one database to another: rows returned and start with an appropriate :attr:`Cursor.arraysize` value.
The default is 100. Then set :attr:`Cursor.prefetchrows` to the ``arraysize``
value. Do not make the sizes unnecessarily large. For example:
.. code-block:: python .. code-block:: python
# setup cursors cur = connection.cursor()
sourceCursor = sourceConnection.cursor()
sourceCursor.arraysize = 1000
targetCursor = targetConnection.cursor()
# perform fetch and bulk insertion cur.prefetchrows = 1000
sourceCursor.execute("select * from MyTable") cur.arraysize = 1000
while True:
rows = sourceCursor.fetchmany() for row in cur.execute("SELECT * FROM very_big_table"):
if not rows: print(row)
break
targetCursor.executemany("insert into MyTable values (:1, :2)", rows) Adjust the values as needed for performance, memory and round-trip usage. For
targetConnection.commit() a large quantity of rows or very "wide" rows on fast networks you may prefer
to leave ``prefetchrows`` at its default value of 2. Keep ``arraysize`` as
big, or bigger than, ``prefetchrows``.
* If you are fetching a fixed number of rows, start your tuning by setting
``arraysize`` to the number of expected rows, and set ``prefetchrows`` to one
greater than this value. (Adding one removes the need for a round-trip to check
for end-of-fetch). For example, if you are querying 20 rows, perhaps to
:ref:`display a page <rowlimit>` of data, set ``prefetchrows`` to 21 and
``arraysize`` to 20:
.. code-block:: python
cur = connection.cursor()
cur.prefetchrows = 21
cur.arraysize = 20
for row in cur.execute("""
SELECT last_name
FROM employees
ORDER BY last_name
OFFSET 0 ROWS FETCH NEXT 20 ROWS ONLY"""):
print(row)
This will return all rows for the query in one round-trip.
* If you know that a query returns just one row then set :attr:`Cursor.arraysize`
to 1 to minimize memory usage. The default prefetch value of 2 allows minimal
round-trips for single-row queries:
.. code-block:: python
cur = connection.cursor()
cur.arraysize = 1
cur.execute("select * from MyTable where id = 1"):
row = cur.fetchone()
print(row)
In cx_Oracle, the ``arraysize`` and ``prefetchrows`` values are only examined In cx_Oracle, the ``arraysize`` and ``prefetchrows`` values are only examined
when a statement is executed the first time. To change the values, create a new when a statement is executed the first time. To change the values, create a new
@ -207,6 +188,30 @@ to 0:
function before cx_Oracle can return them to the application. Setting function before cx_Oracle can return them to the application. Setting
``prefetchrows`` to 0 helps give a consistent flow of data to the application. ``prefetchrows`` to 0 helps give a consistent flow of data to the application.
Prefetching can also be enabled in an external :ref:`oraaccess.xml
<optclientfiles>` file, which may be useful for tuning an application when
modifying its code is not feasible. Setting the size in ``oraaccess.xml`` will
affect the whole application, so it should not be the first tuning choice.
One place where increasing ``arraysize`` is particularly useful is in copying
data from one database to another:
.. code-block:: python
# setup cursors
sourceCursor = sourceConnection.cursor()
sourceCursor.arraysize = 1000
targetCursor = targetConnection.cursor()
# perform fetch and bulk insertion
sourceCursor.execute("select * from MyTable")
while True:
rows = sourceCursor.fetchmany()
if not rows:
break
targetCursor.executemany("insert into MyTable values (:1, :2)", rows)
targetConnection.commit()
.. _roundtrips: .. _roundtrips:
Database Round-trips Database Round-trips
@ -305,8 +310,8 @@ cache.
.. _clientresultcache: .. _clientresultcache:
Client Result Cache Client Result Caching
=================== =====================
cx_Oracle applications can use Oracle Database's `Client Result Cache cx_Oracle applications can use Oracle Database's `Client Result Cache
<https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-35CB2592-7588-4C2D-9075-6F639F25425E>`__. <https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-35CB2592-7588-4C2D-9075-6F639F25425E>`__.
@ -332,7 +337,7 @@ restarting the database, for example:
SQL> STARTUP FORCE SQL> STARTUP FORCE
CRC can alternatively be configured in an :ref:`oraaccess.xml <optclientfiles>` CRC can alternatively be configured in an :ref:`oraaccess.xml <optclientfiles>`
or :ref:`sqlnet.ora <optnetfiles>` file on the Node.js host, see `Client or :ref:`sqlnet.ora <optnetfiles>` file on the Python host, see `Client
Configuration Parameters Configuration Parameters
<https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-E63D75A1-FCAA-4A54-A3D2-B068442CE766>`__. <https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-E63D75A1-FCAA-4A54-A3D2-B068442CE766>`__.