Oracle 2 Indexes on same columns but different order - oracle

I have a table in production environment that has 2 Indexes on a Table with the same columns in the Index but in reversed order.
DDL is
- CREATE INDEX IND_1 ON ORDERS (STORE_ID,DIST_ID)
- CREATE INDEX IND_DL_1 ON ORDERS (DIST_ID,STORE_ID)
Are these two indexes not essentially the same. Why would someone create indexes such a way? Does reversing or changing of column position do something internally?

Indexes are tied to the fields they're indexing, in the order they're being defined in the index. As long as you use the fields in the index, in their left->right order, then index is useable for your query. If you're skipping fields, then the index cannot be used. e.g. given the following index:
CREATE INDEX ind1 ON foo (bar, baz, qux)
then these where clauses will be able to use the index:
WHERE bar=1
WHERE bar=1 AND baz=2
WHERE baz=2 AND bar=1 <--same as before
WHERE bar=1 AND baz=2 AND qux=3
The order you use the indexed fields in the query is not relevant, just that you ARE using them. However, the order they're defined in the index is critical. The following clauses can NOT use the index:
WHERE baz=2 <-- 'bar' not being used
WHERE baz=2 AND qux=3 <-- 'bar' again not being used
WHERE bar=1 AND qux=3 <-- the index can be partially used to find `bar`, but not qux.
For your two cases, there's nothing really wrong with how they're indexed, but it'd be slightly more efficient to index as follows:
(STORE_ID, DIST_ID)
(DIST_ID)
There's no point in indexing store_id in the second index, because the DBMS can use the first index to handle the store_id lookups. It's not a major gain, but still... maintaining indexes is overhead for the DB, and reducing overhead is always a good thing.

Oracle does not have to touch table segments in cases when all the needed information is found in indexes.
In your case these indexes can serve as a quick lookup/translation table STORE_ID => DIST_ID and vice-versa.
Just look at the exec plan for the query where you select only select STORE_ID based on DIST_ID,
the query will only go through index, and will not touch the table itself.
But maybe the reason is different (if any).

Related

Sort by a different index's values

Given two indexes, I'm trying to sort the first based on values of the second.
For example, Index 1 ('Products') has fields id, name. Index 2 ('Prices') has fields id, price.
Struggling to figure out how to sort 'Products' by the 'Prices'.price, assuming the ids match. Reason for this quest is that hypothetically the 'Products' index becomes very large (with duplicate ids), and updating all documents becomes expensive.
Elasticsearch is a document based store, rather than a column based store. What you're looking for is a way to JOIN the two indices, however this is not supported in Elasticsearch. The 'Elasticsearch way' of storing these documents is to have 1 index that contains all relevant data. If you're worried about update procedures taking very long, look into creating an index with an Alias. When you need to do a major update, do it to a new index and only when you're done switch the alias target to the new index, this will allow you to update you data seamlessly

does a compound index in MongoDB improve multified match (not sorting)?

The documentation seems a bit unclear on that.
1)It clearly states that compound indexes DO improve performance of multi-field SORTING (order and direction dependant).
2) There is one phrase which makes me think it will also improve multi field MACH (sql analogy: where a=1 and b=2 and c<5)
https://docs.mongodb.org/v3.0/tutorial/optimize-query-performance-with-indexes-and-projections/
If a query searches multiple fields, create a compound index.
it says nothing about sorting.
So is compound index on fields a,b,c better for matching performance than three single-field indexes for queries like (where a=1 and b=2 and c<5)?
Yes, creating compound indexes improve query performance.
Create a Single-Key Index if All Queries Use the Same, Single Key
If for a particular collection you are using a single key for matching like where a=1
Create Compound Indexes to Support Several Different Queries
If your query uses one or more than one key, it better to use compound indexes.
db.sample.createIndex( { "a": 1, "b": 1, "c":1 } )
You can query on just a, you can query on a combined with b and also you can query on a, b and c. You can use explain() method to get to know what plan your query is using.
Index Intersection might also optimize the performance of your queries. It can support what compound index fails to support.

Oracle string search performance issue

I have a simple search store procedure in Oracle 11GR2 in a table with over 1.6 million records. I am puzzled by the fact that if I want to search for a work inside a column, such as "%boston%", it would take 12 seconds. I have an index on the name collumn.
select description from travel_websites where name like "%boston%";
If I only search for a word start with Boston like "boston%", it only takes 0.15 seconds.
select description from travel_websites where name like "boston%";
I added an index hint and try to force optimizer to use my index on the name column, it did not help either.
select description /*+ index name_idx */ from travel_websites where name like "%boston%";
Any advises would be greatly appreciated.
You cannot use an index range scan for a predicate that has a leading wildcard (i.e. like '%boston%'). This makes sense if you think about how an index is stored on disk-- if you don't know what the first character of the string you are searching is, you can't traverse the index to look for index entries that match that string. You may be able to do a full scan of the index where you read every leaf block and search the name there to see if it contains the string you want. But that requires a full scan of the index plus you then have to visit the table for every ROWID you get from the index in order to fetch any columns that are not part of the index that you just full-scanned. Depending on the relative size of the table and the index and how selective the predicate is, the optimizer may easily decide that it is quicker to just do a table scan if you're searching for a leading wildcard.
Oracle does support full text search but you have to use Oracle Text which would require that you build an Oracle Text index on the name column and use the CONTAINS operator to do the search rather than using a LIKE query. Oracle Text is very robust product so there are quite a few options to consider both in building the index, refreshing the index, and building the query depending on how sophisticated you want to get.
Your index hint is not correctly specified. Assuming there is an index on name, that the name of that index is name_idx, and that you want to force a full scan of the index (just to reiterate, a range scan on the index is not a valid option if there is a leading wildcard), you would need something like
select /*+ index(travel_websites name_idx) */ description
from travel_websites
where name like '%boston%'
There is no guarantee, however, that a full index scan is going to be any more efficient than a full table scan. And it is entirely possible that the optimizer is choosing the index full scan already without the hint (you don't specify what the query plans are for the three queries).
Oracle (and as far as I know most other databases) by default indexes strings so that the index can only be used to look up string matches from the start of the string. That means, a LIKE 'boston%' (startswith) will be able to use the index, while a LIKE '%boston' (endswith) or LIKE '%boston%' (contains) will not.
If you really need indexes that can find substrings fast, you can't use the regular index types for strings, but you can use TEXT indexes which sadly may require slightly different query syntax.

MongoDB: Two-field index vs document field index

I need to index a collection by two fields (unique index), say field1 and field2. What's better approach in terms of performance:
Create a regular two-column index
-or -
Combine those two fields in a single document field {field1 : value, field2 : value2} and index that field?
Note: I will always be querying by those two fields together.
You can keep the columns separate and create a single index that will increase performance when querying both fields together.
db.things.ensureIndex({field1:1, field2:1});
http://www.mongodb.org/display/DOCS/Indexes#Indexes-CompoundKeysIndexes
Having the columns in the same column provides no performance increases, because you must index them the same way:
db.things.ensureIndex({fields.field1:1, fields.field2:1});
http://www.mongodb.org/display/DOCS/Indexes#Indexes-EmbeddedKeys
Or you can index the entire document
db.things.ensureIndex({fields: 1});
http://www.mongodb.org/display/DOCS/Indexes#Indexes-DocumentsasKeys
There could be a possible performance increase, but doubtfully very much. Use the test database, create test data and benchmark some tests to figure it out. We would love to hear your results.
I'd create a compound index over both fields. This'll take up less disk space because you won't need to store the extra combined field, and give you the bonus of an additional index over the first field, i.e. an index over { a:1, b:1 } is also an index over { a:1 }.

Having a string array field as an index, good or bad?

My gut feel is that setting a string (with array elements) field as an index on a table will be bad for performance (where the bulk of the operations done on a table are inserts and updates - the table holds transactional data and its current size is approximately 20 mil records).
The string extends a type with 4 array elements, where all of them aren’t always populated. I need to justify why not to set this field as one of the indexes. I’ve tried searching for answers, reading Kimberley Tripps blog, going through best practises re indexes on MSDN (which only mentions indexes are best on numerics first, then string fields), etc. But none of these mention indexing the table on a field that is of an array type. What reasons can I give to justify not indexing on the string-array field. And if my gut feel is totally wrong and indexes work well on array fields, why so?
A Memo or Container field cannot be part of an index in AX.
Furthermore, columns consisting of the ntext, text, or image data types cannot be specified as columns for an index in SQL Server.
Let's say you have an extended data type ArrElement with 3 additional array elements ArrElement2, ArrElement3, ArrElement4. Creating an index with a field of the ArrElement type in AX will effectively create an index with 4 fields (ArrElement, ArrElement2, ArrElement3, and ArrElement4 - in that order) in SQL Server. You cannot change the order of the array elements in the index, but in my opinion there's really nothing wrong in having such an index if it really serves your purpose. Hope that answers your question.
As #10p noted adding say Dimension as the only field, will create an index of all the array elements: Dimension, Dimension2_, Dimension3_ (which are the names of the SQL table fields).
The value of such an index will depend on the queries performed. If only Dimension[3] is queried, then the index is of no value because Dimension[1] and Dimension[2] is not known.
This could be solved by creating an index for each of the array elements, for example:
Dim1Idx: Dimension[1] (maybe append more fields)
Dim2Idx: Dimension[2] (maybe append more fields)
Dim3Idx: Dimension[3] (maybe append more fields)
Individual array elements can be selected by using the combo-box on the index field.
The value of such indexes should be weighted against the added cost of insertion (and update, if the array values are changed).

Resources