Documentation improvements.
This commit is contained in:
parent
a21e06a60c
commit
b4443c0f9f
|
@ -9,9 +9,8 @@ Overview
|
|||
|
||||
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
|
||||
versions of Python, for example see :ref:`Installing cx_Oracle in Python 2
|
||||
<python2>`
|
||||
- Python 3.5 and higher. Older versions of cx_Oracle may work with older
|
||||
versions of Python.
|
||||
|
||||
- Oracle Client libraries. These can be from the free `Oracle Instant
|
||||
Client
|
||||
|
@ -40,8 +39,8 @@ Quick Start cx_Oracle Installation
|
|||
- Install `Python <https://www.python.org/downloads>`__ 3, if not already
|
||||
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
|
||||
:ref:`Installing cx_Oracle in Python 2 <python2>`.
|
||||
Python 3.5 and higher are supported by cx_Oracle 8. If you use Python 2,
|
||||
then the older cx_Oracle 7.3 will install.
|
||||
|
||||
- Install cx_Oracle from `PyPI
|
||||
<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
|
||||
================================
|
||||
|
||||
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
|
||||
|
||||
cx_Oracle 7.3 was the last version with support for Python 2.
|
||||
|
||||
For other installation options such as installing through a proxy, see
|
||||
instructions above. Make sure the Oracle Client libraries are in the system
|
||||
library search path because cx_Oracle 7 does not support the
|
||||
|
|
|
@ -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
|
||||
additional data copy from Oracle Client's prefetch buffers.
|
||||
|
||||
To tune queries that return an unknown number of rows, estimate the number of
|
||||
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)
|
||||
Choosing values for ``arraysize`` and ``prefetchrows``
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
The best :attr:`Cursor.arraysize` and :attr:`Cursor.prefetchrows` values can be
|
||||
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
|
||||
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
|
||||
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
|
||||
<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.
|
||||
Here are some suggestions for the starting point to begin your tuning:
|
||||
|
||||
One place where increasing ``arraysize`` is particularly useful is in copying
|
||||
data from one database to another:
|
||||
* To tune queries that return an unknown number of rows, estimate the number of
|
||||
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
|
||||
sourceCursor = sourceConnection.cursor()
|
||||
sourceCursor.arraysize = 1000
|
||||
targetCursor = targetConnection.cursor()
|
||||
cur = connection.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()
|
||||
cur.prefetchrows = 1000
|
||||
cur.arraysize = 1000
|
||||
|
||||
for row in cur.execute("SELECT * FROM very_big_table"):
|
||||
print(row)
|
||||
|
||||
Adjust the values as needed for performance, memory and round-trip usage. 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. 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
|
||||
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
|
||||
``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:
|
||||
|
||||
Database Round-trips
|
||||
|
@ -305,8 +310,8 @@ cache.
|
|||
|
||||
.. _clientresultcache:
|
||||
|
||||
Client Result Cache
|
||||
===================
|
||||
Client Result Caching
|
||||
=====================
|
||||
|
||||
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>`__.
|
||||
|
@ -332,7 +337,7 @@ restarting the database, for example:
|
|||
SQL> STARTUP FORCE
|
||||
|
||||
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
|
||||
<https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-E63D75A1-FCAA-4A54-A3D2-B068442CE766>`__.
|
||||
|
||||
|
|
Loading…
Reference in New Issue