Indexing using pg_trgm module not working while using more than one OR operator in the where condition inside the query in postgresql 9.4 - postgresql

Indexing using pg_trgm module not working for me while using more than one OR operator in the where condition. Query is given below.
EXPLAIN ANALYZE
SELECT *
FROM registration
where
data->>'firstName' LIKE '%lali%' OR
data->>'spouseName' LIKE '%lali%' OR
data->>'vhnName' LIKE '%lali%' OR
data ->> 'subCentreName' LIKE '%lali%'
When I run the above I get sequence scan but I expect index scan to happen.
I am using JsonB.
I tried out both gist and gin indexing for all the columns mentioned in the where clause in above query but indexing didn't work for both.
How to do indexing for the case if we use multiple OR operators inside where clause?

A pattern starting with % is worthless in a index search since it can start with anything.

Related

Using IN statement with jsonb type in postgres

I am trying to write a postgres sql query to select jsonb fields from my table and wondering if I can use IN statement with #> jsonb operator
The query I have is
SELECT data FROM catalog WHERE data #> '{"name":{"firstname":"myname"}}'
Above works fine with one value in WHERE condition, is it possible that I could use mutliple json in WHERE condition like along with '{"name":{"firstname":"myname"}}', I also want return records for '{"name":{"firstname":"yourname"}}'
I can do something like below
Select *
FROM catalog
WHERE data ->'name' ->> 'firstname' IN ('myname','yourname')
Whats the best way to do it ?
Starting in the soon to be released v12, you can use JSONPATH to do that.
SELECT data FROM catalog WHERE data ## '$.name.firstname=="myname" || $.name.firstname=="yourname"';
There may be a better to way to write that JSONPATH without the repetition, I'm not an expert there.
Your other choices are the IN you already shown, and multiple #> connected by OR. The different operations are supported by different indexes. If you care about performance, they the "best" way to do it depends on what indexes you already have, or are willing to build, and just how you prefer to write your queries. (Indeed I'd argue the "best" way is not to use JSON in the first place). To use the IN list, you would need an expressional index like:
create index on catalog ((data ->'name' ->> 'firstname') );

Why do Postgres Hstore indexes work for ? (operator) and not for EXIST (function)?

http://www.postgresql.org/docs/9.2/static/hstore.html states:
hstore has GiST and GIN index support for the #>, ?, ?& and ?| operators
Yet the indexes don't work for the EXIST function, which appears to be equivalent to the ? operator.
What is the difference between operators and functions that makes it harder to index one or the other?
Might future versions of the Hstore extension make these truly equivalent?
Lookup the documentation for "CREATE OPERATOR CLASS" which describes how you can create indexing methods for arbitrary operators. You also need to use "CREATE OPERATOR" to create an operator based on the EXIST function first.
(Caveat: I have no experience with hstore)
http://www.postgresql.org/docs/9.0/static/sql-createoperator.html
http://www.postgresql.org/docs/9.0/static/sql-createopclass.html
Here's your problem: PostgreSQL functions are planner-opaque. The planner has no way of knowing that the operator and the function are semantically equivalent. This comes up a lot.
PostgreSQL does have functional indexes so you can index outputs of immutable functions but this may not quite make things work perfectly well here since you'd probably be able to only index which rows return true for a given call, but this could still be very useful with partial indexes. For example you could always do something like:
CREATE INDEX bar_has_aaa ON foo(exists(bar, 'aaa'));
or
CREATE INDEX bar_has_aaa ON foo(id) where exists (bar, 'aaa');
But I don' see this going exactly where you need it to go. Hopefully it points you in the right direction though.
Edit: The following strikes me as a better workaround. Suppose we have a table foo:
CREATE TABLE foo (
id serial,
bar hstore
);
We can create a table method bar_keys:
CREATE FUNCTION bar_keys(foo) RETURNS text[] IMMUTABLE LANGUAGE SQL AS $$
SELECT akeys($1.bar);
$$;
Then we can index that using GIN:
CREATE INDEX foo_bar_keys_idx ON foo USING gin(bar_keys(foo));
And we can use it in our queries:
SELECT * FROM foo WHERE foo.bar_keys #> array['aaa'];
That should use an index. Note you could just index/use akeys directly, but I think a virtual column leads to cleaner syntax.

How to make fulltext search in PostgreSQL useful?

I have a russian dictionary in postgresql 8.4.
I try to use full search but have some troubles.
I dont get any results becouse try to find words by 4-5symbols. For example:
select * from parcels_temp where name_dispatcher ## to_tsquery('Нику');
Get result: 0 rows.
select * from parcels_temp where name_dispatcher ## to_tsquery('Никуд');
Get result: 2 rows. its correct.
I try to do search by words not contained in dictionary. What i gonna do in this case? How can i update dictionary in PostgreSQL?
Its must create column to tsvector or i can use to_tsvector function i queries? Or its more slowly?
Postgresql indexer does not process strings shorter than 3 characters. It is done to reduce index size and generation time.
Obviously, you get nothing. There is way to update dictionary, refer to documentation.
Use GIN index on tsvector field.
1: By default, postgreSQL only matches the whole word. You can opt in to do a prefix matching:
select * from parcels_temp where name_dispatcher ## to_tsquery('Нику:*');
See: https://www.postgresql.org/docs/9.5/static/textsearch-controls.html
3: You can create a column and GIN index on it, or you can just create the index without creating a column. I think they are the same in terms of performance. For details, see:
https://www.postgresql.org/docs/9.5/static/textsearch-tables.html

Query runs slow when NVL is used in Oracle

I have a view when I query this view it runs slow. However if I remove NVL function it is running fast.
I have checked execution plan, when NVL function is used it is not using any index. If NVL function is not used it is index. I tried to specify the index as hint but it did not help. Not sure whether the hint is considered or not while executing.
Below is the view and the query used to create the view.
CREATE OR REPLACE FORCE VIEW "test"(a,b)
select NVL(table1.a,table2.a) a,table2.b from table1 join table2 on table1.id=table2.id
The query that I am using on view is
select * from test where a='XYZ'
Any thoughts what should I do to make above query run fast?
Not sure if you got an answer to this already - You would need to use a Functional based index using NVL(a). By default Oracle will not index null columns, so when you query using NVL, it will perform a full table scan.

Fast search within strings in PostgreSQL

Which is the fastest way to search within string in PostgreSQL (case insensivity):
SELECT col FROM table WHERE another_col ILIKE '%typed%'
or
SELECT col FROM table WHERE another_col ~* 'typed'
How can I turn on showing the time which query need to return results? Something like is on default in mySQL (I am thinking about CLI client).
Both queries are the same, PostgreSQL rewrites ILIKE to ~*. Check the results from EXPLAIN to see this behaviour.
I'm not sure about your question, but the psql-client can show you some timing of the query, using \timing.
Regarding the timing:
One solution is to use the switch for psql that Frank has already mentioned.
When you use EXPLAIN ANALZYE it also includes the total runtime of the query on the server.
I prefer this when comparing the runtime for different versions of a query as it removes the network from the equation.