Closed ghost closed 7 years ago
What are you trying to find out and what operations are really important to you?
The code (which I haven't gone right through) tests some distinct areas. For example it queries from a sequence - is that something you plan to do? Have you tried querying different rows of a large table? Why not set the pool min & max to the same values (& increment to 0) so the sessions are pre-created? How did you decide on the pool settings vs the number of threads? Are you testing your network - the PL/SQL code doesn't do any network traffic, so the overheads are different? Will you only be doing one statement for every connection acquire/release - that may not reflect some real-world (or best practice) scenarios? If pure speed is important, why use not use OCI directly?
I tried running your code. On my machine, which is by no means a fast machine, I am getting a full 100,000 iterations in about 7-8 seconds. The first bit of that time (1/2 a second or so) is for creating the pool and pre-creating the connections. My database is local (on the same machine as the code that is running). Is that true of your case as well? Running remotely will definitely slow things down! As Chris mentioned, running on the server is not the same thing as running on a client -- so the performance I am seeing with the session pool is pretty reasonable I would think.
I played a little with the number of threads. On my machine at least reducing the number of threads to 15 improved throughput -- and there was less startup time. But that is highly dependent on your situation.
Hello,
What I am trying to achieve here is to use a sequence in order to implement a counter. Multiple http clients use a web service and we want to increment a counter atomically under some circumstances. I don't know if this is the best way to increment a counter in oracle. In case you have something else in mind, it would be great if you could share it.
So we need some real world performance, as your link indicates below. We need at least 3K/sec counter increments.
The idea to have static pool with min = max = some value, sounds OK. I will try it immediately.
I have already used OCCI but the performance was not what I want it, so I come up with this implementation (odpi), assuming that my OCCI client code was not good. However I realized that the performance is almost similar either with OCCI or with odpi.
it is interesting that you mentioned PL/SQL. Would it better instead of having the select statement on the client c++ code to invoke a PL/SQL function that does the same thing?
What is important for us is to really ensure that either with OCCI or with ofpi we can do >2K increments per second.
On Fri, 7 Jul 2017 at 05:34, Christopher Jones notifications@github.com wrote:
What are you trying to find out and what operations are really important to you?
The code (which I haven't gone right through) tests some distinct areas. For example it queries from a sequence - is that something you plan to do? Have you tried querying different rows of a large table? Why not set the pool min & max to the same values (& increment to 0) so the sessions are pre-created http://docs.oracle.com/cd/E82638_01/JJUCP/optimizing-real-world-performance.htm#JJUCP-GUID-BC09F045-5D80-4AF5-93F5-FEF0531E0E1D? How did you decide on the pool settings vs the number of threads? Are you testing your network - the PL/SQL code doesn't do any network traffic, so the overheads are different? Will you only be doing one statement for every connection acquire/release - that may not reflect some real-world (or best practice) scenarios? If pure speed is important, why use not use OCI directly?
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/oracle/odpi/issues/15#issuecomment-313571228, or mute the thread https://github.com/notifications/unsubscribe-auth/AajvyfkxmrzA-gwoarnnp4y8Ed8lzGmIks5sLZkagaJpZM4OQBgL .
With your code on my machine I was getting 12,500 increments/second. So I think that qualifies. :-)
But is that all you are trying to do with the database?
Hello , I really appreciate the fact that you are responding to my question.
No, we have a lot of tables that support our service and oracle of course qualifies.
But as I have explained above, I wanted to find out if oracle offers a solution for the counter increment problem. We need a way to increment a value really fast.
On Fri, 7 Jul 2017 at 06:06, Anthony Tuininga notifications@github.com wrote:
But is that all you are trying to do with the database?
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/oracle/odpi/issues/15#issuecomment-313575368, or mute the thread https://github.com/notifications/unsubscribe-auth/AajvyT5BOzSQe8ADPsM5Z9T62U9uOW4wks5sLaDCgaJpZM4OQBgL .
What is the proper way to do this?
Select for update?
On Fri, 7 Jul 2017 at 06:13, ellampros . el.lampros@gmail.com wrote:
Hello , I really appreciate the fact that you are responding to my question.
No, we have a lot of tables that support our service and oracle of course qualifies.
But as I have explained above, I wanted to find out if oracle offers a solution for the counter increment problem. We need a way to increment a value really fast.
On Fri, 7 Jul 2017 at 06:06, Anthony Tuininga notifications@github.com wrote:
But is that all you are trying to do with the database?
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/oracle/odpi/issues/15#issuecomment-313575368, or mute the thread https://github.com/notifications/unsubscribe-auth/AajvyT5BOzSQe8ADPsM5Z9T62U9uOW4wks5sLaDCgaJpZM4OQBgL .
What is the proper way to do this?
If all you want is the counter to be incremented, then the select statement is the fastest; but if you have other things going on at the same time, putting it into a PL/SQL procedure makes the most sense. You want to reduce the number of round trips, especially if you are across a network and the database isn't local to your application.
You are straying into DB performance questions. I'll see if I can get someone with wider performance tuning skills to comment on sequence usage.
Do you have any other requirements for the 'counter'? Don't forget that sequences (specially with caching) may end up with number range 'gaps'.
A customer OCI program will like be faster than OCCI or ODPI-C.
You mean the select on the sequence and not the "for update"
On Fri, 7 Jul 2017 at 06:17, Anthony Tuininga notifications@github.com wrote:
What is the proper way to do this?
If all you want is the counter to be incremented, then the select statement is the fastest; but if you have other things going on at the same time, putting it into a PL/SQL procedure makes the most sense. You want to reduce the number of round trips, especially if you are across a network and the database isn't local to your application.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/oracle/odpi/issues/15#issuecomment-313576666, or mute the thread https://github.com/notifications/unsubscribe-auth/Aajvybb5hvneV6LdOAE1uw93osMO9iA_ks5sLaNfgaJpZM4OQBgL .
You mean the select on the sequence and not the "for update"
Yes. The "for update" clause is when you intend to update the table or view you are querying -- which you definitely don't want to do in this case!
Christopher,
The atomic counter increment is the hot issue right now.
As I said the performance requirements are not extra ordinary, so I would like to resolve this in Oracle.
It would be great if a "counter expert" could help
On Fri, 7 Jul 2017 at 06:23, ellampros . el.lampros@gmail.com wrote:
You mean the select on the sequence and not the "for update"
On Fri, 7 Jul 2017 at 06:17, Anthony Tuininga notifications@github.com wrote:
What is the proper way to do this?
If all you want is the counter to be incremented, then the select statement is the fastest; but if you have other things going on at the same time, putting it into a PL/SQL procedure makes the most sense. You want to reduce the number of round trips, especially if you are across a network and the database isn't local to your application.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/oracle/odpi/issues/15#issuecomment-313576666, or mute the thread https://github.com/notifications/unsubscribe-auth/Aajvybb5hvneV6LdOAE1uw93osMO9iA_ks5sLaNfgaJpZM4OQBgL .
@leflabs define 'atomic'. Are 'gaps' OK?
I have read about those gaps.
If the performance Is ok with "no cache" in the sequence, I will use no cache.
On the other hand if the counter can reach 1 million, then 200 gaps are OK.
If the counter can reach just 5 hits, then no gaps are allowed.
On Fri, 7 Jul 2017 at 06:31, Christopher Jones notifications@github.com wrote:
@leflabs https://github.com/leflabs define 'atomic'. Are 'gaps' OK?
— You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub https://github.com/oracle/odpi/issues/15#issuecomment-313578203, or mute the thread https://github.com/notifications/unsubscribe-auth/AajvyW15Hvj3pO985QkZoTiFjad_joTCks5sLaacgaJpZM4OQBgL .
@anthony-tuininga I downloaded a VM from oracle with the database on, installed some dev tools and I compiled the demo cpp file in the same machine with the DB. It is true that it is much much faster (with CACHE "on").
However since we have opened the discussion here, I would be glad to know if this the canonical/normal way to deal with counters in Oracle Database.
I got some comments. In summary, revisit your design and think about what you want the numbers for.
Are you going to use them to insert into the DB? Then consider using PL/SQL for all that logic.
Generating unique, possibly monotonically increasing, values is non-trivial, and if they are needed very fast and with high concurrency, they should always be generated as close as possible to their actual use. So if they are needed ONLY on the application server side, don't ask the database to generate them.
Or maybe you could create batches of numbers on each application server.
A lot depends on your goals, and on potential architectures (do you have multiple 'mid tiers', aka ODPI-C apps?)
The existing sample benchmark code doesn't really capture any of this, so it doesn't prove much.
@cjbj and @anthony-tuininga thanks very much for this thread. I will probably re visit my design.
Regards.
@leflabs let us know what you decide.
I'll close this since the question has been answered but feel free to create a new issue if a new question pops up! Thanks.
I would like to make a question regarding performance
Below a small "demo" file that is used to measure execution time. I want to update a sequence with nextvval 100K times.
The sequence is created with the above script, and using the workbench like this
it takes less than 2 seconds for the counter to reach 100K.
However the following code wants more than 7 seconds to reach 10K (an order of magnitude less). I am wondering if there is something better I can do, or if I miss something. Is it possible using the library to reach better number, ie 2K-3K per second?
In order to compile please use
g++ t_main.cpp -std=c++11 -lboost_system -lboost_thread -lodpic -ldl
I used a simple thread pool from boost.
Do we misuse the library somehow?
It is a little bit critical for us, since we want to decide if we will use oracle for a high performance server.
Thank you very much in advance.