“SELECT COUNT(*)” is slow, even with where clause

后端 未结 8 1586
抹茶落季
抹茶落季 2020-11-30 23:22

I\'m trying to figure out how to optimize a very slow query in MySQL (I didn\'t design this):

SELECT COUNT(*) FROM change_event me WHERE change_event_id >         


        
相关标签:
8条回答
  • 2020-11-30 23:55

    To make the search more efficient, although I recommend adding index. I leave the command for you to try the metrics again

    CREATE INDEX ixid_1 ON change_event (change_event_id);
    

    and repeat query

    SELECT COUNT(*) FROM change_event me WHERE change_event_id > '1212281603783391';
    

    -JACR

    0 讨论(0)
  • 2020-11-30 23:56

    I've run into behavior like this before with IP geolocation databases. Past some number of records, MySQL's ability to get any advantage from indexes for range-based queries apparently evaporates. With the geolocation DBs, we handled it by segmenting the data into chunks that were reasonable enough to allow the indexes to be used.

    0 讨论(0)
  • 2020-11-30 23:57

    Check to see how fragmented your indexes are. At my company we have a nightly import process that trashes our indexes and over time it can have a profound impact on data access speeds. For example we had a SQL procedure that took 2 hours to run one day after de-fragmenting the indexes it took 3 minutes. we use SQL Server 2005 ill look for a script that can check this on MySQL.

    Update: Check out this link: http://dev.mysql.com/doc/refman/5.0/en/innodb-file-defragmenting.html

    0 讨论(0)
  • 2020-11-30 23:58

    MySQL does say "Using where" first, since it does need to read all records/values from the index data to actually count them. With InnoDb it also tries to "grab" that 4 mil record range to count it.

    You may need to experiment with different transaction isolation levels: http://dev.mysql.com/doc/refman/5.1/en/set-transaction.html#isolevel_read-uncommitted

    and see which one is better.

    With MyISAM it would be just fast, but with intensive write model will result in lock issues.

    0 讨论(0)
  • 2020-12-01 00:04

    InnoDB uses clustered primary keys, so the primary key is stored along with the row in the data pages, not in separate index pages. In order to do a range scan you still have to scan through all of the potentially wide rows in data pages; note that this table contains a TEXT column.

    Two things I would try:

    1. run optimize table. This will ensure that the data pages are physically stored in sorted order. This could conceivably speed up a range scan on a clustered primary key.
    2. create an additional non-primary index on just the change_event_id column. This will store a copy of that column in index pages which be much faster to scan. After creating it, check the explain plan to make sure it's using the new index.

    (you also probably want to make the change_event_id column bigint unsigned if it's incrementing from zero)

    0 讨论(0)
  • 2020-12-01 00:07

    Run "analyze table_name" on that table - it's possible that the indices are no longer optimal.

    You can often tell this by running "show index from table_name". If the cardinality value is NULL then you need to force re-analysis.

    0 讨论(0)
提交回复
热议问题