Unix Technical Forum

SEO

vBulletin Search Engine Optimization


Go Back   Unix Technical Forum > Database Server Software > PostgreSQL > Pgsql Performance

Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 04-19-2008, 10:46 AM
Ravi Chemudugunta
 
Posts: n/a
Default Performance Implications of Using Exceptions

Hello,

I have a typical many to many join table, in this instance it is
capturing the multiplicity described as "one person can have many
rooms and one room can have many persons". Further the join expresses
where in the room the person is sitting, a seat number. I am creating
a function to abstract this away, if there is no record with the same
person and room the insert otherwise if it already exists update the
record with the new seat value.

create table person_room (
id serial,
person_id int,
room_id int,
seat varchar(255),
unique (person_id, room_id)
);

-- version 1
create or replace function add_person_to_room(person int, room int, s
varchar(255)) as $$
begin
insert into person_room(person_id, room_id, seat) values (person, room, s);
exception when unique_violation then
update person_room set seat = s where (person_id = person) and
(room_id = room);
end;
$$ language 'plpgsql';

-- version 2
create or replace function add_person_to_room(person int, room int, s
varchar(255)) as $$
declare
i int;
begin
select into i id from person_room where (person_id = person) and
(room_id = room);
if (not found) then
insert into person_room(person_id, room_id, seat) values
(person, room, s);
else
update person_room set seat = s where (person_id = person) and
(room_id = room);
end;
$$ language 'plpgsql';


Which version is faster?
Does the exception mechanism add any overhead?
Which is more cleaner?

-ravi

--
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 04-19-2008, 10:46 AM
Stephen Frost
 
Posts: n/a
Default Re: Performance Implications of Using Exceptions

* Ravi Chemudugunta (chemuduguntar@gmail.com) wrote:
> Which version is faster?


In general I would recommend that you benchmark them using
as-close-to-real load as possible again as-real-as-possible data.

> Does the exception mechanism add any overhead?


Yes, using exceptions adds a fair bit of overhead. Quote from the
documentation found here:
http://www.postgresql.org/docs/8.3/s...tructures.html

Tip: A block containing an EXCEPTION clause is significantly more
expensive to enter and exit than a block without one. Therefore, don't
use EXCEPTION without need.

> Which is more cleaner?


That would be in the eye of the beholder, generally. Given the lack of
complexity, I don't think 'cleanness' in this case really matters all
that much.

Enjoy,

Stephen

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFH8YdTrzgMPqB3kigRAv2uAJwOED/o2a1SAxCYjf8PQdbQndt/OQCeMCUI
WpOiyc5Qi9fYu8kVjVvJxWk=
=mDi4
-----END PGP SIGNATURE-----

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 04-19-2008, 10:46 AM
Stephen Denne
 
Posts: n/a
Default Re: Performance Implications of Using Exceptions

Stephen Frost wrote
> * Ravi Chemudugunta (chemuduguntar@gmail.com) wrote:
> > Which version is faster?

>
> In general I would recommend that you benchmark them using
> as-close-to-real load as possible again as-real-as-possible data.
>
> > Does the exception mechanism add any overhead?

>
> Yes, using exceptions adds a fair bit of overhead. Quote from the
> documentation found here:
> http://www.postgresql.org/docs/8.3/s...l-control-stru
> ctures.html
>
> Tip: A block containing an EXCEPTION clause is significantly more
> expensive to enter and exit than a block without one. Therefore, don't
> use EXCEPTION without need.
>
> > Which is more cleaner?

>
> That would be in the eye of the beholder, generally. Given
> the lack of
> complexity, I don't think 'cleanness' in this case really matters all
> that much.


A third option is to update, if not found, insert.

Regards,
Stephen Denne.

Disclaimer:
At the Datamail Group we value team commitment, respect, achievement, customer focus, and courage. This email with any attachments is confidential andmay be subject to legal privilege. If it is not intended for you please advise by reply immediately, destroy it and do not copy, disclose or use it in any way.
__________________________________________________ ________________
This email has been scanned by the DMZGlobal Business Quality
Electronic Messaging Suite.
Please see http://www.dmzglobal.com/dmzmessaging.htm for details.
__________________________________________________ ________________



--
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 04-19-2008, 10:46 AM
Ravi Chemudugunta
 
Posts: n/a
Default Re: Performance Implications of Using Exceptions

Hi, thanks for the quick reply.

> In general I would recommend that you benchmark them using
> as-close-to-real load as possible again as-real-as-possible data.


I am running a benchmark with around 900,000 odd records (real-load on
the live machine ) ... should show hopefully some good benchmarking
results for the two methods.

> That would be in the eye of the beholder, generally. Given the lack of
> complexity, I don't think 'cleanness' in this case really matters all
> that much.


I would like to make a comment that is that the only downside I saw of
using the exception approach was that if for some reason someone
forgot to add the unique constraint to the table, it would be a bit of
a nightmare-ness. (I am porting some code into the server where the
schema does not have these constraints setup, only in the devel
database).

Will reply back with my conclusions, I am expecting a large difference.

Cheers,

ravi

--
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5 (permalink)  
Old 04-19-2008, 10:46 AM
Robins Tharakan
 
Posts: n/a
Default Re: Performance Implications of Using Exceptions

Coming to think of it.

Would it fine to consider that an UPDATE query that found no records to
update is (performance wise) the same as a SELECT query with the same WHERE
clause ?

As in, does an UPDATE query perform additional overhead even before it finds
the record to work on ?

*Robins*


On Tue, Apr 1, 2008 at 7:53 AM, Robins Tharakan <robins@pobox.com> wrote:

> I get into these situations quite often and use exactly what stephen
> pointed out.
>
> Do an Update, but if not found, do an insert. Its (by and large) better
> than your version 2 since here you may skip running the second query (if the
> record exists) but in version 2, two queries are *always* run. And
> considering that exception is heavy, this may be a good attempt to give a
> try as well.
>
> update person_room set seat = s where (person_id = person) and (room_id =
> room);
> if not found then
> insert into person_room(person_id, room_id, seat) values (person, room,
> s);
> end if
>
> Robins
>
>
>
> On Tue, Apr 1, 2008 at 6:26 AM, Stephen Denne <
> Stephen.Denne@datamail.co.nz> wrote:
>
> > Stephen Frost wrote
> > > * Ravi Chemudugunta (chemuduguntar@gmail.com) wrote:
> > > > Which version is faster?
> > >
> > > In general I would recommend that you benchmark them using
> > > as-close-to-real load as possible again as-real-as-possible data.
> > >
> > > > Does the exception mechanism add any overhead?
> > >
> > > Yes, using exceptions adds a fair bit of overhead. Quote from the
> > > documentation found here:
> > > http://www.postgresql.org/docs/8.3/s...l-control-stru
> > > ctures.html
> > >
> > > Tip: A block containing an EXCEPTION clause is significantly more
> > > expensive to enter and exit than a block without one. Therefore, don't
> > > use EXCEPTION without need.
> > >
> > > > Which is more cleaner?
> > >
> > > That would be in the eye of the beholder, generally. Given
> > > the lack of
> > > complexity, I don't think 'cleanness' in this case really matters all
> > > that much.

> >
> > A third option is to update, if not found, insert.
> >
> > Regards,
> > Stephen Denne.
> >
> > Disclaimer:
> > At the Datamail Group we value team commitment, respect, achievement,
> > customer focus, and courage. This email with any attachments is confidential
> > and may be subject to legal privilege. If it is not intended for you please
> > advise by reply immediately, destroy it and do not copy, disclose or use it
> > in any way.
> > __________________________________________________ ________________
> > This email has been scanned by the DMZGlobal Business Quality
> > Electronic Messaging Suite.
> > Please see http://www.dmzglobal.com/dmzmessaging.htm for details.
> > __________________________________________________ ________________
> >
> >
> >
> > --
> > Sent via pgsql-performance mailing list (
> > pgsql-performance@postgresql.org)
> > To make changes to your subscription:
> > http://www.postgresql.org/mailpref/pgsql-performance
> >

>
>


Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #6 (permalink)  
Old 04-19-2008, 10:46 AM
Tom Lane
 
Posts: n/a
Default Re: Performance Implications of Using Exceptions

"Robins Tharakan" <tharakan@gmail.com> writes:
> Would it fine to consider that an UPDATE query that found no records to
> update is (performance wise) the same as a SELECT query with the same WHERE
> clause ?


> As in, does an UPDATE query perform additional overhead even before it finds
> the record to work on ?


The UPDATE would fire BEFORE STATEMENT and AFTER STATEMENT triggers, if
there are any. Also, it would take a slightly stronger lock on the
table, which might result in blocking either the UPDATE itself or some
concurrent query where a plain SELECT would not've.

There might be some other corner cases I've forgotten. But in the basic
case I think your assumption is correct.

regards, tom lane

--
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #7 (permalink)  
Old 04-19-2008, 10:46 AM
James Mansion
 
Posts: n/a
Default Re: Performance Implications of Using Exceptions

Stephen Denne wrote:
> A third option is to update, if not found, insert.
>
>

I find myself having to do this in Sybase, but it sucks because there's
a race - if there's no row updated then there's no lock and you race
another thread doing the same thing. So you grab a row lock on a
sacrificial row used as a mutex, or just a table lock. Or you just
accept that sometimes you have to detect the insert fail and retry the
whole transaction. Which is sucky however you look at it.

I think the 'update or insert' or 'merge' extensions make a degree
of sense. At least in psql one can use the lightweight lock manager.



--
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #8 (permalink)  
Old 04-19-2008, 10:46 AM
chemuduguntar@gmail.com
 
Posts: n/a
Default Re: Performance Implications of Using Exceptions

> I find myself having to do this in Sybase, but it sucks because there's
> a race - if there's no row updated then there's no lock and you race
> another thread doing the same thing. So you grab a row lock on a
> sacrificial row used as a mutex, or just a table lock. Or you just
> accept that sometimes you have to detect the insert fail and retry the
> whole transaction. Which is sucky however you look at it.


hmm should I be worried ?

I am doing an 'update if not found insert', in some cases I have found
that I need to select anyway, for e.g. take away 20 dollars from this
person;

(all variables prefixed with _ are local variables)

select into _money money from person_money where person_id = _person;
if (not found) then
insert into person_money (person_id, money) values (_person, -
_requested_amount);
else
update person_money set money = money - _requested_amount where
person_id = _person;
-- return new quantity
return _money - _requested_quantity; -- <- i need the quantity so I
have to select here.
end if;

if I am not mistaken your are saying that between the select and the
if (not found) then ... end if; block ... another concurrent process
could be executing the same thing and insert ... while in the first
thread found is still 'false' and so it ends up inserting and over
writing / causing a unique violation or some kind?

BTW, I did a benchmark with and without exceptions, the exceptions
version was very slow, so slow that I ended up killing it ... I am
sure it would have taken atleast 5 hours (was already 3 hours in) ...
versus, 25 mins! I guess the trouble was that I was using exceptions
to overload 'normal' flow ... i.e. update if exists else update is not
an exceptional circumstance and so exceptions are a bad choice.

It would be interesting to see how much overhead exception containing
functions present when they do not throw any exceptions ... for never
to every few records to all the time ... maybe I will try it with my
parsing functions (which catch exceptions thrown by substring()).
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #9 (permalink)  
Old 04-19-2008, 10:46 AM
Robins Tharakan
 
Posts: n/a
Default Re: Performance Implications of Using Exceptions

I think James was talking about Sybase. Postgresql on the other hand has a
slightly better way to do this.

SELECT ... FOR UPDATE allows you to lock a given row (based on the SELECT
.... WHERE clause) and update it... without worrying about a concurrent
modification. Of course, if the SELECT ... WHERE didn't bring up any rows,
you would need to do an INSERT anyway.

Read more about SELECT ... FOR UPDATE here:
http://www.postgresql.org/docs/8.3/s...R-UPDATE-SHARE

*Robins*

On Thu, Apr 3, 2008 at 2:48 PM, chemuduguntar@gmail.com <
chemuduguntar@gmail.com> wrote:

> > I find myself having to do this in Sybase, but it sucks because there's
> > a race - if there's no row updated then there's no lock and you race
> > another thread doing the same thing. So you grab a row lock on a
> > sacrificial row used as a mutex, or just a table lock. Or you just
> > accept that sometimes you have to detect the insert fail and retry the
> > whole transaction. Which is sucky however you look at it.

>
> hmm should I be worried ?
>
> I am doing an 'update if not found insert', in some cases I have found
> that I need to select anyway, for e.g. take away 20 dollars from this
> person;
>
> (all variables prefixed with _ are local variables)
>
> select into _money money from person_money where person_id = _person;
> if (not found) then
> insert into person_money (person_id, money) values (_person, -
> _requested_amount);
> else
> update person_money set money = money - _requested_amount where
> person_id = _person;
> -- return new quantity
> return _money - _requested_quantity; -- <- i need the quantity so I
> have to select here.
> end if;
>
> if I am not mistaken your are saying that between the select and the
> if (not found) then ... end if; block ... another concurrent process
> could be executing the same thing and insert ... while in the first
> thread found is still 'false' and so it ends up inserting and over
> writing / causing a unique violation or some kind?
>
> BTW, I did a benchmark with and without exceptions, the exceptions
> version was very slow, so slow that I ended up killing it ... I am
> sure it would have taken atleast 5 hours (was already 3 hours in) ...
> versus, 25 mins! I guess the trouble was that I was using exceptions
> to overload 'normal' flow ... i.e. update if exists else update is not
> an exceptional circumstance and so exceptions are a bad choice.
>
> It would be interesting to see how much overhead exception containing
> functions present when they do not throw any exceptions ... for never
> to every few records to all the time ... maybe I will try it with my
> parsing functions (which catch exceptions thrown by substring()).
>
> --
> Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-performance
>


Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #10 (permalink)  
Old 04-19-2008, 10:46 AM
James Mansion
 
Posts: n/a
Default Re: Performance Implications of Using Exceptions

Robins Tharakan wrote:
>
> I think James was talking about Sybase. Postgresql on the other hand
> has a slightly better way to do this.
>
> SELECT ... FOR UPDATE allows you to lock a given row (based on the
> SELECT ... WHERE clause) and update it... without worrying about a
> concurrent modification. Of course, if the SELECT ... WHERE didn't
> bring up any rows, you would need to do an INSERT anyway.

How does that help?

If the matching row doesn't exist at that point - what is there to get
locked?

The problem is that you need to effectively assert a lock on the primary
key so that you can update
the row (if it exists) or insert a row with that key (if it doesn't)
without checking and then inserting and
finding that some other guy you were racing performed the insert and you
get a duplicate key error.

How does Postgresql protect against this?

James


--
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 04:41 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
UnixAdminTalk.com

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512