1

How's that possible when I added index to a column it slowed down the execution time? Trying to get rid of the query from slow queries log. My slow-query settings:

slow_query_log = 1
long_query_time = 1 # seconds
log_queries_not_using_indexes = 1
slow_query_log_file = /var/log/mysql-slow.log

describe table index slows query

4
  • Are you using InnoDB or MyISAM? Commented May 31, 2013 at 12:37
  • 2
    pls add SQL_NO_CACHE when you want to benchmark queries because the results might be compromised due to the fact that the second query can get the result from mysql cache Commented May 31, 2013 at 12:50
  • Thanks, always learning. I updated the image. Commented May 31, 2013 at 12:55
  • 1
    Indexes aren't magic, a bad index will slow down the query. There exists something called cardinality. That's a number telling us how many unique values there are in a set. In a set (1,2,2,2) there are 4 members but only 2 unique values. If you have a column banner and you index it while column has 10 unique values - if you have 200k rows then the cardinality is 10/200000. That's a low number and MySQL won't gain anything. Consequently, operations using primary key are fast, because PK cardinality is always 1. Commented May 31, 2013 at 13:30

2 Answers 2

4

Indexes do not always speed up execution. The effect of an index depends primarily on the "selectivity" of the query: how many rows are processed by the overall query.

In general, reading a database (a "full table scan") is an efficient operation. The database engine knows what pages it needs to read and can read ahead to get them. Such I/O often occurs in the background, while processing the pages is in the foreground. When the next page is needed though, there is a good chance it is already in the page cache.

The performance issue with full table scans is that tables are big. So even efficient reads take time. When you are looking for one row in a million ("needle-in-the-haystack" queries), the reads are a waste of time. This is where indexes fix things.

However, say you have 100 records per page and you are reading more than 1% of the records. On average, every page will need to be read -- whether you are using an index or a full-table scan. The problem is that index reads are less efficient than scan reads. A read-ahead mechanism doesn't help them, because the reads are random.

This problem can be further exacerbated through something called thrashing. If the table does not fit into memory, then each random read is likely to be a "cache miss", incurring the overhead of a read from disk. The full table scan would just read the data, and with a decent look-ahead system, there would be no cache misses.

In your example, you could increase the selectivity of the index by including both banner and event in the index (these are compared using equality) and one of the other fields.

Sign up to request clarification or add additional context in comments.

6 Comments

Tried with adding index banner and event ALTER TABLE mod_banner ADD INDEX banner_event (banner, event), but still over 100ms :P i.imgur.com/IxWoPZU.png
Removing ORDER BY made it instant. i.imgur.com/ZUQxksi.png But I need the one with the lowest last_view
One question: if reading from the index hurts performance, why does not the engine decide to not use them?
Instead of dealing with the WHERE the solution was dealing with the ORDER, adding INDEX on the last_view column i.imgur.com/uDu9oyT.png
@JanDvorak - MySQL keeps count of index cardinality. If the cardinality is lower than magic number (I don't remember what that number is to be honest), then it will prefer a table scan. However, MySQL can't know whether traversing the index will be faster than doing the table scan, because as far as I know - index algorithm implementation depends on the engine being used. In this case, it's MyISAM, and apparently its B-tree implementation isn't as good as InnoDB's. I read many people saying that InnoDB's B-tree implementation is one of the best there is.
|
0

Depending on structure of the data on disk, it might be faster to just load the entire db/column and sort/filter it in ram (which will likely happen when no index exists), than to traverse a sparsed index on disk. I don't know if this applies to your specific context or if you have another issue here though.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.