How to add a PostgreSQL GIN index on a uuid in Postgres 9.6 - postgresql

I'm trying to add a GIN index that includes a UUID in a Postgres 9.6 database. Technically it is a composite index, with composite GIN support coming from the btree_gin plugin.
I try to create the index with this statement:
CREATE EXTENSION btree_gin;
CREATE INDEX ix_tsv ON text_information USING GIN (client_id, text_search_vector);
but I get this error:
ERROR: data type uuid has no default operator class for access method "gin"
HINT: You must specify an operator class for the index or define a default operator class for the data type.
client_id is data type uuid and text_search_vector is a tsvector. I don't think the composite/btree_gin factor is actually relevant, as I get the same error trying to create the index on just client_id alone, but hopefully if there is a solution to this, it is one that will work with a composite index also.
I found PostgreSQL GIN index on array of uuid , which seems to suggest that it should be possible (if an array of UUIDs can be done, then surely an individual UUID can be done). However, the solution there was pretty opaque to me - it's not immediately obvious how to modify this solution to support a single UUID.
I would prefer a solution that doesn't involve casting the UUID to another type in the index or in another column, as I would rather not have to write specialized queries with casts in them (we are using django ORM to generate queries atm).

It is possible for GIN indexes. But not before Postgres 11, where it was added. The release notes:
Allow btree_gin to index bool, bpchar, name and uuid data types (Matheus Oliveira)
So the simple solution is to upgrade to Postgres 11. This should be good news for you:
April 9, 2019: Cloud SQL now supports PostgreSQL version 11.1 Beta
Or, in many cases you can alternatively use a GiST index, for which the same was introduced with Postgres 10, already. The release notes:
Add indexing support to btree_gist for the UUID data type (Paul Jungwirth)
Related:
How to use uuid with postgresql gist index type?
If neither is an option, you are back to what you wanted to avoid:
casting the uuid to another type in the index
You can create an expression index on a (consistent!) text representation or, theoretically, on two bigint columns derived from the uuid. But the first makes the index considerably bigger and slower and the second creates much more complication ...
The syntax of the cast is simple enough though: uuid::text. In an index expression that requires an extra set of parentheses. With the additional module btree_gin installed:
CREATE INDEX ix_uuid_tsv ON text_information USING GIN ((client_id::uuid), tsv);
Related:
Postgres using an index for one table but not another
What is the optimal data type for an MD5 field?
Would index lookup be noticeably faster with char vs varchar when all values are 36 chars
Or you could backport the feature from Postgres 11 - which is not an option with a hosted service like Google Cloud SQL for PostgreSQL as you mentioned in a comment. And I hardly see the use case where one would be skilled enough to implement the backport, but not to upgrade to Postgres 11.

Related

What is the difference between LTree and LTree_Gist in Postgresql?

In create table wizard of PGAdmin 4 when you open the column type drop-down menu, there is a type named ltree_gist.
Knowing that GIST is probably the best index option to use upon ltree columns, I suspect that ltree_gist is just ltree with an index defined on it as it is reasonable to create a ltree type column with a GIST index in just one move. But looks like its not that!
Long story short, could someone please explain the difference between ltree and ltree_gist in PGAdmin4 interface?
I could not find anything in the documentation.
ltree_gist is an implementation detail that is used for the implementation of GiST index support for ltree values. It is used for storing index entries.
That type cannot be used in SQL or table definitions directly.

Crate DB exception, no viable alternative at input 'VARCHAR'

I'm using Elastic search to store large amount of data to make it searchable, but for configuration items I'm still using HSQL DB.
Is it possible to eliminate HSQL DB completely and use my existing Elastic search in combination with Crate DB?
Things I have tried:
tried connecting to my existing Elastic search using Crate driver and Crate client but I got an exception No handler found for action "crate_sql". Does that mean I cannot use my existing ES and have to use inbuilt ES in crateDB??
After connecting to crateDB elastic search (and not my existing ES). I was able to get connection using CrateDriver and run SQL queries. But in one of module I'm creating table using below command:
create table some_table_name
(
id VARCHAR(256),
userName VARCHAR(256),
fieldName VARCHAR(256),
primary key (id),
unique (userName, fieldName)
);
...but then I got an exception:
io.crate.action.sql.SQLActionException: line 1:28: no viable alternative at input 'VARCHAR'
Does that mean I cannot write create table query using SQL syntax and SQL data types?
I know it will work if I use string data type instead of varchar, but I don't want to change all those queries now.
1)
No you cannot use existing ES nodes together with Crate. The whole SQL analyzer/planner/execution layer is done server side, not client side. In fact the crate clients are rather dumb.
2)
You'll have to change the types and also remove / change anything that isn't supported by crate. For example defaults or unique constraints aren't supported (up to 0.39 - in the future support might be added)
In your case the varchar type isn't valid in Crate, instead you'll have to use "string".
See Data Types Documentation for a list of supported data types.

PostgreSQL indexes for hstore boolean attributes

I have an hstore column called extras and I have defined there many attributes some of them are boolean and I would like to index some of them for example extras->'delivered' in this case which would be the best way to index some of these attributes.
If you answer could you tell me if your technique applies for decimal or other types.
Thanx.
Indexing individual keys in a hstore field
The current hstore version doesn't have typed values. All values are text. So you can't directly define a "boolean" index on an hstore value. You can, however, cast the value to boolean and index the cast expression.
CREATE INDEX sometable_extras_delivered_bool
ON sometable ( ((extras->'delivered')::boolean) );
Only queries that use the expression (extras->'delivered')::boolean) will benefit from the index. If the index expression uses a cast, the query expressions must too.
This b-tree index on a hstore field will be less efficient to create and maintain than a b-tree index of a boolean col directly in the table. It'll be much the same to query.
Indexing all keys in a hstore field
If you want a general purpose index that indexes all hstore keys, you can only index them as text. There's no support for value typing in hstore in PostgreSQL 9.3.
See indexes on hstore.
This is useful when you don't know in advance which keys you need to index.
(Users on later, pre-release at time of writing versions of PostgreSQL with the json-compatible hstore version 2 will find that their hstore supports typed values).
Reconsider your data model
Frankly, if you're creating indexes on fields in a hstore that you treat as boolean, then consider re-thinking your data model. You are quite likely better off having this boolean as a normal field of the table that contains the hstore.
You can store typed values in json, but you don't get the GIN / GiST index support that's available for hstore. This will improve in 9.4 or 9.5, with hstore 2 adding support for typed, nested, indexable hstores and a new json representation being built on top of that.
Partial indexes
For booleans you may also want to consider partial index expressions where the boolean is a predicate on another index, instead of the actual indexed column. E.g:
CREATE INDEX sometable_ids_delivered ON sometable(id) WHERE (delivered);
or, for the hstore field:
CREATE INDEX sometable_ids_delivered ON sometable(id) WHERE ((extras->'delivered')::boolean);
Exactly what's best depends on your queries.

Use of DB2 Indices with several columns

We are trying to locate a performance problem and wondering if an index is being used.
We have a table with a composite key, "ID" and "Version", both integers.
We have a select that tries to find the max of "ID". (This is done via Entity framework if it makes a difference).
Will this use the index or will it do a table scan?
If the ID column is defined as the first part of a multi-column index, then DB2 will use that index to determine the MAX(). It will still probably try to use the index if you did a MAX(VERSION), but if you have a very large table, this may take quite a bit of processing.
You can confirm this using the explain facilities (link is for Linux/Unix/Windows 9.7).

Postgres Indexing?

I am a newbie in postgres. I have a column named host (string varchar2) in a table which has around 20 million rows. How do I use indexing to optimize my search to find particular host. Also, this column will be updated daily do I need to write trigger indexing at particular interval? If yes, how do I do that? (For Records I am using Ruby and Rails 3)
Assuming you're doing exact matches, you should just be able to create the index and leave it:
CREATE INDEX host_index ON table_name (host)
The query optimizer should just use that automatically.
You may wish to specify other options such as the collation to use.
See the PostgreSQL docs for CREATE INDEX for more information.
I'd suggest using BRIN Index since its introduction from PostgreSQL 9.5 rather than the conventional btree index.
For text search, it is recommended that you use GIN or GiST index types.
https://www.postgresql.org/docs/9.5/static/textsearch-indexes.html
Another possibility is that if you were only performing exact matching in the host column, i.e., no inequality comparisons (>, <) and partial matching (like, wildcard) involved, you may consider converting host to a hash integer to speed up the search significantly.