$work uses OpenNMS to monitor our various devices (servers, switches, routers, printers etc), mostly via SNMP. Today, while looking at the various events that had been recorded, I noticed that a relatively simple search was taking more than 2 minutes to process through ~250,000 event rows (plus associated rows in other tables). I turned on query logging (log_statements = ‘all’ && service postgresql reload), and re-ran the search from the web interface.
Lo and behold, the culprit was revealed – the search went something like
UPPER(eventlogmsg) LIKE ‘%value%’
Even if that field was indexed,the use of the ‘%’ on the front would negate the use of the index. I threw the query into PGAdmin, and discovered that the query plan that PostgreSQL chose was a pair of nested loop joins – unpleasant to say the least. A quick gander at the docs, and a few SQL statements later, and I had a full-text index on the eventlogmsg field. Several test queries convinced me that it was much faster, so I threw the new query into PGAdmin and asked for the pretty query plan. Two hash joins and a sort, and a query time of 31 milliseconds; or more than 5000 times faster.
So, I’ve filed a Bugzilla entry for this with the OpenNMS team – unfortunately it’s specific to PostgreSQL 8.3, but that’s something that can probably be determined at run-time and install-time. Hopefully they agree that it’s a worthwhile performance change, as full-text indexes won’t actually help the LIKE usage – the code will have to change to generate new SQL statements.