0

I have a MySQL(InnoDB) table in which I have a large number of rows(a couple of million). I'm doing queries as such:

SELECT  SQL_CALC_FOUND_ROWS `a` 
FROM  `logs`  
WHERE  `connect_timestamp`  > 10000 
ORDER  BY  `connect_timestamp`  DESC 
LIMIT 1

I have a normal index added to the column, however a query like this takes up to 20 seconds, is there a better way?

Sevle
  • 3,109
  • 2
  • 19
  • 31
Saulius Antanavicius
  • 1,371
  • 6
  • 25
  • 55

2 Answers2

1

Edit based on comments from spencer7593 and Martin:

A simple count + select query might be much faster than one SQL_CALC_FOUND_ROWS. see: Which is fastest? SELECT SQL_CALC_FOUND_ROWS FROM `table`, or SELECT COUNT(*)

I suggest running both your original query and:

SELECT  count(*)
FROM  `logs`  
WHERE  `connect_timestamp`  > 10000

plus:

SELECT  `a`
FROM  `logs`  
WHERE  `connect_timestamp`  > 10000 
ORDER  BY  `connect_timestamp`  DESC 
LIMIT 1

Best even to run all with EXPLAIN added to measure (and add) the runtimes and see the difference, you can also add SQL_NO_CACHE to simulate a first run. see: https://www.percona.com/blog/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/

If that doesn't help at all i suggest to look into the following:

Things you can try:

  • Index the column which is used for searching (you seem to have already done so)
  • Make a view for specific queries that are to be executed often.
  • Try caching the specific table if the server has memory for it.
  • Also like Martin said in the comments, Put EXPLAIN in front of the query to see which part of the query is taking up all the time. Maybe there is something you can change about it.

Those are the things i can come up with.

Community
  • 1
  • 1
Jester
  • 1,408
  • 1
  • 9
  • 21
  • 1
    isn't the `a` a column that is being called by the `select`? – Martin Mar 31 '16 at 14:45
  • if not, then surely a `COUNT` SQL would be better than OPs current SQL? – Martin Mar 31 '16 at 14:46
  • Oh, my bad :) renaming the selected variable in this case, but renaming the result definitely won't slow the query down i think. I'll remove it, thanks! – Jester Mar 31 '16 at 14:48
  • 2
    This answer might also mention the potential performance impact of **`SQL_CALC_FOUND_ROWS`**, and suggest that running two separate queries... 1) "`SELECT a ... ORDER BY ... LIMIT 1`" and 2) "`SELECT COUNT(*)`" may be significantly faster than a single query. – spencer7593 Mar 31 '16 at 14:54
  • Oh i didn't even delve too deep into that (never used it myself) you're right. i think you're right, a simple count might perform much better – Jester Mar 31 '16 at 14:57
  • I remain unconvinced. I tried 5 cases in my code of `SQL_CALC_FOUND_ROWS`. All were at least as fast as the 2-query approach; most were faster. I am using InnoDB, not MyISAM (as the old Percona blog was). – Rick James Mar 31 '16 at 23:51
0
INDEX(connect_timestamp, a)

This will be a "covering" index, thereby speeding up the SQL_CALC_FOUND_ROWS as well as the SELECT ... LIMIT 1.

It will have to scan from the end of the index all the way back to 10000. How many rows is that?

If connect_timestamp is some types of CHAR instead of some type of INT, then you have another problem. Please provide SHOW CREATE TABLE.

Rick James
  • 135,179
  • 13
  • 127
  • 222