Postgresql ILIKE versus TSEARCH

后端 未结 3 881
天涯浪人
天涯浪人 2020-12-17 02:07

I have a query with a number of test fields something like this:

SELECT * FROM some-table
  WHERE field1 ILIKE \"%thing%\"
     OR field2 ILIKE \"%thing\"
           


        
相关标签:
3条回答
  • 2020-12-17 02:49

    A full text search setup is not identical to a "contains" like query. It stems words etc so you can match "cars" against "car".

    If you really want a fast ILIKE then no standard database index or FTS will help. Fortunately, the pg_trgm module can do that.

    • http://www.postgresql.org/docs/9.1/static/pgtrgm.html
    • http://www.depesz.com/2011/02/19/waiting-for-9-1-faster-likeilike/
    0 讨论(0)
  • 2020-12-17 02:53

    One thing that is very important: NO B-TREE INDEX will ever improve this kind of search:

    where field ilike '%SOMETHING%'
    

    What I am saying is that if you do a:

    create index idx_name on some_table(field);
    

    The only access you will improve is where field like 'something%'. (when you search for values starting with some literal). So, you will get no benefit by adding a regular index to field column in this case.

    If you need to improve your search response time, definitely consider using FULL TEXT SEARCH.

    0 讨论(0)
  • 2020-12-17 03:00

    Adding a bit to what the others have said.

    First you can't really use an index based on a value in the middle of the string. Indexes are tree searches generally, and you have no way to know if your search will be faster than just scanning the table, so PostgreSQL will default to a seq scan. Indexes will only be used if they match the first part of the string. So:

    SELECT * FROM invoice
      WHERE invoice_number like 'INV-2012-435%'
    

    may use an index but like '%44354456%' cannot.

    In general in LedgerSMB we use both, depending on what kind of search we are doing. You might see a search like:

    select * from parts
      WHERE partnumber ilike ?  || '%'
        and plainto_tsquery(get_default_language(), ?) @@ description;
    

    So these are very different. Use each one where it makes the most sense.

    0 讨论(0)
提交回复
热议问题