CYBERTEC PostgreSQL Logo

Detecting unstable execution times in PostgreSQL

12.2016 / Category: / Tags: |

Do you have queries with unstable execution times? You have a query which is sometimes slow and sometimes just lightning fast. The question is usually: Why? Maybe this little post can be inspiring and shade some light one some of your performance issues, which might bug you in your daily life.

Reasons for unstable execution times

There are many reasons why the very same type of query might cause such “unpredictable” behavior. The following list shows some of the most common reasons:

  • Unstable execution plans
  • Excessive buffer usage
  • Locking-related troubles

Of course, there are some other possible reasons (other processes exhausting CPU/IO, checkpoints, etc.), however, given the possible scope of a post, I would like to focus on excessive buffer usage and its consequences.

Setting up an example

To demonstrate what can happen, I have compiled a simple example. All it does, is to load 50 million rows into a table. The main point is that the data will be stored on disk in random order. Then an index is created:

After running VACUUM the following query shows, what this is all about:

In this query almost 10.000 buffers are used. The trouble now is: If the data is coming from RAM (shared_buffers or OS filesystem cache)  everything is somewhat fine, and execution times will be within an acceptable range. Even running the query a second time will speed up things considerably:

We are down to 26 ms.

Random disk I/O

Now let us assume for a second that there are no cache hits. Our system contains an old disk from uncle Sam's hardware store. What would happen to the execution time of the query?

Let us do some math (assuming disk seek time to be 12 ms):

9775 blocks * 12 ms = 117.300 milliseconds

In case of an old mechanical disk, the query would inevitably take around 2 minutes to complete. 2 minutes vs. 26ms – that is actually quite a significant difference.

The question is: Which conclusions can we draw? The first conclusion is that you should try to write your queries in a way that you don't need so many buffers in the first place. The second thing you can do is to try to keep data close together using index organized (a.k.a. column ordered) tables.

In PostgreSQL the CLUSTER command allows you to achieve exactly that:

Keep in mind though that the clustering effect will reduce over time as rows get changed (thus you would normally want a Cron job there) but running the very same query using an index organized table will be A LOT faster:

You will also see that the number of buffers used has been greatly reduced, which makes the execution time of the query better – even if the cache hit rates tend to be close to zero.

In case you need any assistance, please feel free to contact us.
 


In order to receive regular updates on important changes in PostgreSQL, subscribe to our newsletter, or follow us on Facebook or LinkedIn.

2 responses to “Detecting unstable execution times in PostgreSQL”

  1. Don't forget to disable transparent hugepages! We had very unstable performance on our production databases for a long time. The query runtimes were completely unpredictable. Usually fast, sometimes pausing for up to a second for no apparent reason, even on trivial single PK lookup queries. Disabling transparent hugepages made all the difference.

    echo never > /sys/kernel/mm/transparent_hugepage/defrag
    echo never > /sys/kernel/mm/transparent_hugepage/enabled

Leave a Reply

Your email address will not be published. Required fields are marked *

CYBERTEC Logo white
CYBERTEC PostgreSQL International GmbH
Römerstraße 19
2752 Wöllersdorf
Austria

+43 (0) 2622 93022-0
office@cybertec.at

Get the newest PostgreSQL Info & Tools


    This site is protected by reCAPTCHA and the Google Privacy Policy & Terms of Service apply.

    ©
    2024
    CYBERTEC PostgreSQL International GmbH
    phone-handsetmagnifiercrosscross-circle
    linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram