0

I am having trouble with the following query taking quite a long time to process when results are large. The limit and offset can change as this is used with pagination. The range on capture_timestamp can also change, but in this example is finding ALL results (between 0 and 9999999999 - this field is an int of utc timestamp). The issue seems to be the ORDER BY taking up most of the processing time. It looks like it uses user_id for the table join, but then never uses anything for the ordering.

On the logs table I have the following indexes :

PRIMARY : activity_id
user_id : (user_id, capture_timestamp)
capture_timestamp : capture_timestamp (added this to see if by itself would make a difference - it did not)

There are keys setup for all the ON joins.

This particular query for example has 2440801 results (the logs table itself is currently holding 18332067 rows), but I am only showing the first 10 sorted by capture_timestamp and it takes roughly 7 seconds to return the results.

SELECT
    logs.activity_id,
    users.username,
    computers.computer_name,
    computers.os,
    logs.event_title,
    logs.event_target,
    logs.capture_timestamp

FROM computers
INNER JOIN users
    ON users.computer_id = computers.computer_id
INNER JOIN logs
    ON logs.user_id = users.user_id AND logs.capture_timestamp BETWEEN :cw_date_start AND :cw_date_end
    
WHERE computers.account_id = :cw_account_id AND computers.status = 1
ORDER BY logs.capture_timestamp DESC
LIMIT 0,10

analyze :

Array
(
    [0] => Array
        (
            [ANALYZE] => {
  "query_block": {
    "select_id": 1,
    "r_loops": 1,
    "r_total_time_ms": 6848.2,
    "filesort": {
      "sort_key": "logs.capture_timestamp desc",
      "r_loops": 1,
      "r_total_time_ms": 431.25,
      "r_limit": 10,
      "r_used_priority_queue": true,
      "r_output_rows": 11,
      "temporary_table": {
        "table": {
          "table_name": "computers",
          "access_type": "ref",
          "possible_keys": ["PRIMARY", "account_id_2", "account_id"],
          "key": "account_id_2",
          "key_length": "4",
          "used_key_parts": ["account_id"],
          "ref": ["const"],
          "r_loops": 1,
          "rows": 294,
          "r_rows": 294,
          "r_total_time_ms": 0.4544,
          "filtered": 100,
          "r_filtered": 100,
          "attached_condition": "computers.`status` = 1"
        },
        "table": {
          "table_name": "users",
          "access_type": "ref",
          "possible_keys": ["PRIMARY", "unique_filter"],
          "key": "unique_filter",
          "key_length": "4",
          "used_key_parts": ["computer_id"],
          "ref": ["db.computers.computer_id"],
          "r_loops": 294,
          "rows": 1,
          "r_rows": 3.415,
          "r_total_time_ms": 0.7054,
          "filtered": 100,
          "r_filtered": 100,
          "using_index": true
        },
        "table": {
          "table_name": "logs",
          "access_type": "ref",
          "possible_keys": ["user_id", "capture_timestamp"],
          "key": "user_id",
          "key_length": "4",
          "used_key_parts": ["user_id"],
          "ref": ["db.users.user_id"],
          "r_loops": 1004,
          "rows": 424,
          "r_rows": 2431.1,
          "r_total_time_ms": 4745.3,
          "filtered": 100,
          "r_filtered": 100,
          "index_condition": "logs.capture_timestamp between '0' and '9999999999'"
        }
      }
    }
  }
}
        )

)

Is there anything I can do here to speed these up? When the result set is smaller everything is pretty much immediate although I guess that is because there isn't as much sorting to do.

user756659
  • 3,372
  • 13
  • 55
  • 110

0 Answers0