Live data from Hacker News

PostgreSQL when it is not your job

reinout.vanrees.org

21–30 of 44 posts

Re: PostgreSQL when it is not your job

#21
Part of the reason why PostgreSQL has so any knobs is that these things are not always thing that cookie cutter approaches work with. Although if you do need to worry about these, it probably is your job and you probably are at least going to learn it.

I am not convinced about his list of "stupid db tricks you should not do." For example:

1) Sessions in the db are sometimes a good thing and sometimes not. They do have a real performance cost (we have a query in LedgerSMB that for large db's takes 20x longer because of having to do this, but the performance cost is necessary and still worth it, though we will probably offer non-web-based alternatives instead later where this wont be necessary). Of course that query is actually using another table to provide "discretionary locks" of rows to a session.... and those locks MUST persist across transactions because of the fact we are mapping to a series of HTTP requests...

2) I dont know about celery queues, but with listen/notify, you can do some really cool message queuing in PostgreSQL.

3) Usually when my app has to store files attached to data, I usually find that it's simpler to put it in the db than the filesystem. That guarantees that the files are in the backups among other things. Also for larger files, PostgreSQL's lob interface (up to 2gb) provides seek operations and more. performance issues here end up occurring outside PostgreSQL.

I am with him on very long-running transactions.

COPY is good for some things, but if you are trying to create more portable code you probably want to do something like insert foo (....) values (...), (....), (....)....

I would also suggest it is important to know the difference between LIKE '%this%' and full text searching on PostgreSQL. These are not simple drop-in equivalents. However additionally LIKE '%this%' cannot use an index (though like 'this%' can, and you can do full text indexing on Pg).

Re: PostgreSQL when it is not your job

#22

Some of the suggestions make PostgreSQL seem less mature than InnoDB, still: "[don't put] sessions in the DB", "[don't put] constantly-updated counters in the database", and "[don't put] task queues in the database." My forum gets almost a million page views daily; we store all our data in a(n) InnoDB database, including sessions, task queues, and constantly updated counters. They work just fine and are not even bott…

Sessions in the db are fine, depending on what you are doing with them. LedgerSMB for example uses them to track who is doing what right now in the db, as well as maintain per-user locks that have to persist across db transactions.

In most workflows there is no significant performance penalty here. The only problem is where we are checking those locks and trying to obtain them if they are not held by someone else. This is a significant problem and currently makes a query in a large db take about 20x as long.

It all depends on what you are doing. But yeah trying to have extra-transactional locks so you can do reliable locking across HTTP requests tying it to the session sucks :-)

Re: PostgreSQL when it is not your job

#23
post #13

Earlier quoted context omitted.

I don't remember specifically, but I believe it was in the thousands to low tens of thousands of rows. It's also not consistent. I've seen larger IN() clauses that never have a problem, and smaller ones that consistently do. It's been on my very low priority to-do list to put together some demo cases for the mailing lists, because overnight to < 4s just from that little refactor isn't the greatest...

Are we talking about IN clauses that contain a correlated subquery or something the optimizer would have a hard time determining was independent of outer context?

PostgreSQL is able to convert correlated subqueries with IN () clauses into joins in most cases. My guess is that it could have been two queries refactored into one.

Re: PostgreSQL when it is not your job

#24

THIS Thanks Even better if it was a quick guide to all quirks PSQL Dear DBAs, PostgreSql may be great and etc, but if I need to spin a DB for testing/proof of concept, you bet I'm going to use MySQL 20 out of 10 times. "Go RTFM" sorry, I lost count of how many times I had to set up MySQL or PSQL and MySQL is much more intuitive and easy to work with. PSQL is sincerely a waste of time and energy for small things. If I…

I see why you were downvoted.

I used to agree that mysql was far more pleasant than psql but I don't has been true since Pg 7.3. I get frustrated with mysql and having to go read the manual when I need to look up some syntax detail (in psql it's \h sql command, for example \h ALTER TABLE). Also the on-line help for psql is great. \? if you want a list of psql commands.

I would also say that if you see pgsql as a whole as being a waste of time for small things but MySQl as being the choice, the only justification for that can be lack of familiarity. I will say though (and I am totally biassed here by having worked in Pgsql increasingly over the last 12 years) that the more familiar I become with Pgsql the nicer it becomes, while the more familiar I become with MySQL the less I like it.

Re: PostgreSQL when it is not your job

#25

Part of the reason why PostgreSQL has so any knobs is that these things are not always thing that cookie cutter approaches work with. Although if you do need to worry about these, it probably is your job and you probably are at least going to learn it. I am not convinced about his list of "stupid db tricks you should not do." For example: 1) Sessions in the db are sometimes a good thing and sometimes not. They do hav…

Actually since PostgreSQL 9.1 LIKE '%this%' is indexable with the pg_trgm contrib module. Since it is based on the trigrams in your search query it obviously has its caveats, generally the longer the query the more effective the index lookup is. I would imagine for example '%th%' requires a full table/index scan since it contains zero trigrams.

http://www.postgresql.org/docs/9.1/static/pgtrgm.html#AEN137...

Re: PostgreSQL when it is not your job

#26
post #25

Part of the reason why PostgreSQL has so any knobs is that these things are not always thing that cookie cutter approaches work with. Although if you do need to worry about these, it probably is your job and you probably are at least going to learn it. I am not convinced about his list of "stupid db tricks you should not do." For example: 1) Sessions in the db are sometimes a good thing and sometimes not. They do hav…

Actually since PostgreSQL 9.1 LIKE '%this%' is indexable with the pg_trgm contrib module. Since it is based on the trigrams in your search query it obviously has its caveats, generally the longer the query the more effective the index lookup is. I would imagine for example '%th%' requires a full table/index scan since it contains zero trigrams. http://www.postgresql.org/docs/9.1/static/pgtrgm.html#AEN137...

But pg_trgm isn't really the same either, is it? I have looked at pg_trgm primarily for handling misspellings and suggested alternatives.

Also it wasn't clear to me how "%this%" would be differentiated from "his thin snake."

Re: PostgreSQL when it is not your job

#27
One question on avoiding giant IN clauses with Django?

Say I have a class called Fridge, and a classes called Vegetables and Condiments.

Both of these have ManyToMany relationships between themselves and Fridge.

So something like:

    class Fridge(models.Model):
         condiments = models.ManyToManyField(Condiments)
         vegetables = models.ManyToManyField(Vegetables)

And here we have a QuerySet that represents our white fridges:

    qs = Fridges.objects.filter(color='white')
First query:

"Given a list of condiment IDs, get me all the fridges that have ANY of those condiments in them (modifying the original QuerySet).""

Second query:

"Given a list of vegetable IDs, get me all the fridges that have ALL of those vegetables in them (modifying the original QuerySet)."

How on earth would I do that without building a list of fridge IDs and adding an IN clause to my queryset?

Here are solutions that do it with IN clauses:

First query:

        condiment_ids = [...] # list of condiment IDs
        condiments = Condiment.objects.filter(
            id__in=condiment_ids).all()
        condiment_fridges = None
        for condiment in condiments:
            qs = condiment.fridge_set.all()
            if not condiment_fridges:
                condiment_fridges = qs
            else:
                condiment_fridges = condiment_fridges | qs
        qs = qs.filter(id__in=[l.id for l in condiment_fridges])
Second query:

        vegetable_ids = [...] # list of vegetable IDs
        vegetables = vegetable.objects.filter(id__in=vegetable_ids).all()
        vegetable_fridges = None
        for vegetable in vegetables:
            qs = vegetable.location_set.all()
            if not vegetable_fridges:
                vegetable_fridges = qs
            else:
                vegetable_fridges = vegetable_fridges & qs
        qs = qs.filter(id__in=[l.id for l in vegetable_fridges])
These solutions seem horrible and hackish and I was wondering if there was a better way to do them with Django. Something like object HAS these objects or object HAS ALL of these objects.

Should I just post this on StackOverflow instead?

Re: PostgreSQL when it is not your job

#28

Some of the suggestions make PostgreSQL seem less mature than InnoDB, still: "[don't put] sessions in the DB", "[don't put] constantly-updated counters in the database", and "[don't put] task queues in the database." My forum gets almost a million page views daily; we store all our data in a(n) InnoDB database, including sessions, task queues, and constantly updated counters. They work just fine and are not even bott…

You don't worry about VACUUM with InnoDB, but that doesn't mean you never feel the pain of the cleanup of old row versions. See 'purge thread spiral of death' for more details.

Re: PostgreSQL when it is not your job

#29

This advice is just copypasta. It's also pretty dangerous and wrong. Example: "shared-buffers. below 2GB: set it to 20% of full memory, below 32GB: 25% of your full memory." -- Don't do this. Set it to around 20% of your memory if you have a small machine, such as a vps or desktop. If you have lots of memory, set it between 2GB and 4GB. Anything above 8GB exceeds what it is designed to handle and can cause major perf…

"Anything above 8GB exceeds what it is designed to handle and can cause major performance problems, such as the database becoming unresponsive for 1-2 minutes."

Can you please expand on that? What version did you test, on what hardware, and what workload?

Re: PostgreSQL when it is not your job

#30
post #25

Earlier quoted context omitted.

Actually since PostgreSQL 9.1 LIKE '%this%' is indexable with the pg_trgm contrib module. Since it is based on the trigrams in your search query it obviously has its caveats, generally the longer the query the more effective the index lookup is. I would imagine for example '%th%' requires a full table/index scan since it contains zero trigrams. http://www.postgresql.org/docs/9.1/static/pgtrgm.html#AEN137...

But pg_trgm isn't really the same either, is it? I have looked at pg_trgm primarily for handling misspellings and suggested alternatives. Also it wasn't clear to me how "%this%" would be differentiated from "his thin snake."

Yes, pg_trgm was built for that but someone figured out how LIKE could be hacked to use the trigram indexes (gist_trgm_ops, gin_trgm_ops). So if you have a * _trgm_ops index on the column normal LIKE and ILIKE queries may use that index.

I assume your example would be a false index hit which then is necessary to verify against the real value. The same would apply to make sure 'This' is not a hit when doing a case sensitive search for '%this%'. So index-only LIKE scans are not possible with * _trgm_ops indexes.

EDIT: I just realized how awesome the extensibility of PostgreSQL is. An extension can make a core operator such as LIKE indexable in an entirely new way without touching the core code.

Post reply on HN