couchbase index for variable array in query - indexing

I tried to make and run some N1QL query that find document some field is matched with element of variable array in query. but speed of the query is too slow.
The query is like below.
select * from bucket where tp='type' and
tm between 1484618520 and 1484618615 and nm='name' and
checked=false and (bucket.gm in ["TEST","TEST2"])
["TEST","TEST2"] part is variable depend on condition.
I want to speedup this query.
How can I create index for this query including variable array?
Thanks.

I solved this problem by using below command.
create index new_index on bucket(gm,tp,tm,nm,checked) using gsi;
I set the "gm" field as leading key of new index.
Then the query speed was totally improved.

Related

PostgreSQL calculated index for JSON value doesn't work in peewee?

I am using peewee to create a PostgreSQL calculated index from a value in a JSON column.
Here is the code
idx = Tweet.index(Tweet.data['x'], name='x')
Tweet.add_index(idx)
This produces the following SQL which does not work.
CREATE INDEX IF NOT EXISTS "x" ON "tweet" ("data"->>'x')
According to the PostgreSQL docs, the JSON expression must be wrapped by two sets of parentheses, as follows:
CREATE INDEX IF NOT EXISTS "x" ON "tweet" (("data"->>'x'))
Am I doing something wrong, or is this a bug in Peewee? How can I fix that?
That seems like a postgres bug since it's arbitrary as all hell. In this case, just add the index explicitly using the SQL() helper:
Tweet.add_index(SQL('create index ...'))

Schema index for words in a string

I have a large amount of nodes which have the property text containing a string.
I want to find all nodes which text contains a given string (exact match). This can be done using the CONTAINS operator.
MATCH (n)
WHERE n.text CONTAINS 'keyword'
RETURN n
Edit: I am looking for all nodes n where n.text contains the substring 'keyword'. E.g. n.text = 'This is a keyword'.
To speed up this I want to create an index for each word. Is this possible using the new Schema Indexes?
(Alternatively this could be done using a legacy index and adding each node to this index but I would prefer using a schema index)
Absolutely. Given that you are looking for an exact match you can use a schema index. Judging from your question you probably know this but to create the index you will need to assign your node a label and then create the index on that label.
CREATE INDEX ON :MyLabel(text)
Then at query time the cypher execution index will automatically use this index with the following query
MATCH (n:MyLabel { text : 'keyword' })
RETURN n
This will use the schema index to look up the node with label MyLabel and property text with value keyword. Note that this is an exact match of the complete value of the property.
To force Neo4j to use a particular index you can use index hints
MATCH (n:MyLabel)
USING INDEX n:MyLabel(text)
WHERE n.text = 'keyword'
RETURN n
EDIT
On re-reading your question I am thinking you are not actually looking for a full exact match but actually wanting an exact match on the keyword parameter within the text field. If so, then...no, you cannot yet use schema indexes. Quoting Use index with STARTS WITH in the Neo4j manual:
The similar operators ENDS WITH and CONTAINS cannot currently be solved using indexes.
If I understand your question correctly, a legacy index would accomplish exactly what you're looking to do. If you don't want to have to maintain the index for each node you create/delete/update, you can use auto indexing (http://jexp.de/blog/2014/03/full-text-indexing-fts-in-neo4j-2-0/).
If you're looking to only use schema indexing, another approach would be to store each keyword as a separate node. Then you could use a schema index for finding relevant keyword nodes which then map to the node they exist on. Just a thought.

How to overcome ( SQL Like operator ) performance issues?

I have Users table contains about 500,000 rows of users data
The Full Name of the User is stored in 4 columns each have type nvarchar(50)
I have a computed column called UserFullName that's equal to the combination of the 4 columns
I have a Stored Procedure searching in Users table by name using like operatior as below
Select *
From Users
Where UserFullName like N'%'+#FullName+'%'
I have a performance issue while executing this SP .. it take long time :(
Is there any way to overcome the lack of performance of using Like operator ?
Not while still using the like operator in that fashion. The % at the start means your search needs to read every row and look for a match. If you really need that kind of search you should look into using a full text index.
Make sure your computed column is indexed, that way it won't have to compute the values each time you SELECT
Also, depending on your indexing, using PATINDEX might be quicker, but really you should use a fulltext index for this kind of thing:
http://msdn.microsoft.com/en-us/library/ms187317.aspx
If you are using index it will be good.
So you can give the column an id or something, like this:
Alter tablename add unique index(id)
Take a look at that article http://use-the-index-luke.com/sql/where-clause/searching-for-ranges/like-performance-tuning .
It easily describes how LIKE works in terms of performance.
Likely, you are facing such issues because your whole table shoould be traversed because of first % symbol.
You should try creating a list of substrings(in a separate table for example) representing k-mers and search for them without preceeding %. Also, an index for such column would help. Please read more about KMer here https://en.m.wikipedia.org/wiki/K-mer .
This will not break an index and will be more efficient to search.

PostgreSQL only returns result when adding additional AND clause

I have a query like this:
SELECT boroughs.name
FROM boroughs, uniroads
WHERE uniroads.normalizedName='6 AVENUE'
AND st_intersects(boroughs.geometry, uniroads.way)
AND boroughs.name='Brooklyn'
0 results
But when I run it, it returns no results. However, I'm able to find the specific row in the table I'd like it to return, and when I add a clause asking for that particular row, it works fine:
SELECT boroughs.name
FROM boroughs, uniroads
WHERE uniroads.normalizedName='6 AVENUE'
AND st_intersects(boroughs.geometry, uniroads.way)
AND boroughs.name='Brooklyn'
AND uniroads.osm_id='23334071'
1 result
I'm using Postgres 9.2.2.0 with PostGIS through Postgres.app.
A guess.
uniroads.osm_id looks like a Key, therefore it is most likely to be indexed.
AND uniroads.osm_id='23334071' clause is causing (another, perhaps?) index to be used, thus this might mean (some?) originally used indexes are corrupted.
Maybe the following might help?
REINDEX TABLE boroughs;
REINDEX TABLE uniroads;
In any case, EXPLAIN ANALYZE wanted for both queries, as well as complete definitions of tables involved.

Optimizing like '%text%' condition without removing it

I need to optimize query although I don't have access to application source code.
Simplified query goes like this:
select from eu.myview where name like '%text%'
Until now I was solving this by generating full text index and replacing like with contains condition. That worked fine. However, in this case I don't have access to application source code and I can't remove like condition. I have access to database and I can change eu.myview source.
Is there anything I can do to optimize this query?
No.
The leading % invalidates use of index seeks so every row must be examined... whether via an index or table scan