Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Same query uses different indexes?

Can a select query use different indexes if a change the value of a where condition?

The two following queries use different indexes and the only difference is the value of the condition and typeenvoi='EXPORT' or and typeenvoi='MAIL'

select numenvoi,adrdest,nomdest,etat,nbessais,numappel,description,typeperiode,datedebut,datefin,codeetat,codecontrat,typeenvoi,dateentree,dateemission,typedoc,numdiffusion,nature,commentaire,criselcomp,crisite,criservice,chrono,codelangueetat,piecejointe, sujetmail, textemail
            from v_envoiautomate
            where etat=0 and typeenvoi='EXPORT'
            and nbessais<1 


select numenvoi,adrdest,nomdest,etat,nbessais,numappel,description,typeperiode,datedebut,datefin,codeetat,codecontrat,typeenvoi,dateentree,dateemission,typedoc,numdiffusion,nature,commentaire,criselcomp,crisite,criservice,chrono,codelangueetat,piecejointe, sujetmail, textemail
            from v_envoiautomate
            where etat=0 and typeenvoi='MAIL'
            and nbessais<1

Can anyone give me an explanation?

like image 551
Roxana Avatar asked Jun 30 '09 08:06

Roxana


People also ask

Can a query use multiple indexes?

MySQL can use multiple-column indexes for queries that test all the columns in the index, or queries that test just the first column, the first two columns, the first three columns, and so on.

Why does the same query take different times?

Either you are getting different performance because the system is under a different sort of load, you are getting different performance because of data volume changes, or you are getting different performance because you are getting different query plans.

Can a query use multiple indexes SQL Server?

SQL Server may decide to seek both indexes and join the result. Yes, two indexes may be used when 1st WHERE condition is covered by Index1 and 2nd WHERE condition is covered by Index2. In this case SQL may decide to use Index Seek for both indexes and then do Hash Match (Inner Join). It's not that uncommon.

Can you have multiple indexes?

To combine multiple indexes, the system scans each needed index and prepares a bitmap in memory giving the locations of table rows that are reported as matching that index's conditions. The bitmaps are then ANDed and ORed together as needed by the query. Finally, the actual table rows are visited and returned.


2 Answers

Details on indexes are stored as statistics in a histogram-type dataset in SQL Server.

Each index is chunked into ranges, and each range contains a summary of the key values within that range, things like:

  • range High value
  • number of values in the range
  • number of distinct values in the range (cardinality)
  • number of values equal to the High value

...and so on.

You can view the statistics on a given index with:

DBCC SHOW_STATISTICS(<tablename>, <indexname>)

Each index has a couple of characteristics like density, and ultimately selectivity, that tell the query optimiser how unique each value in an index is likely to be, and how efficient this index is at quickly locating records.

As your query has three columns in the where clause, it's likely that any of these columns might have an index that could be useful to the optimiser. It's also likely that the primary key index will be considered, in the event of the selectivity of other indexes not being high enough.

Ultimately, it boils down to the optimiser making a quick judgement call on how many page reads will be necessary to read each your non-clustered indexes + bookmark lookups, with comparisons with the other values, vs. doing a table scan.

The statistics that these judgements are based on can vary wildly too; SQL Server, by default, only samples a small percentage of any significant table's rows, so the selectivity of that index might not be representative of the whole. This is particularly problematic where you have highly non-unique keys in the index.

In this specific case, I'm guessing your typeenvoi index is highly non-unique. This being so, the statistics gathered probably indicate to the optimiser that one of the values is rarer than the other, and the likelihood of that index being chosen is increased.

like image 158
Jeremy Smyth Avatar answered Oct 13 '22 04:10

Jeremy Smyth


The query optimiser in SQL Server (as in most modern DBMS platforms) uses a methodology known as 'cost based optimisation.' In order to do this it uses statistics about the tables in the database to estimate the amount of I/O needed. The optimiser will consider a number of semantically equivalent query plans that it generates by transforming a basic query plan generated by parsing the statement.

Each plan is evaluated for cost by a heuristic based on the statistics maintained about the tables. The statistics come in various flavours:

  • Table and index row counts

  • Distributions histograms of the values in individual columns.

If the ocurrence of 'MAIL' vs. 'EXPORT' in the distribution histograms is significantly different the query optimiser can come up with different optimal plans. This is probably what happened.

like image 30
ConcernedOfTunbridgeWells Avatar answered Oct 13 '22 02:10

ConcernedOfTunbridgeWells