MySQL查询慢1000倍,极限略高(不偏移)

时间:2018-10-01 13:57:02

标签: mysql sql performance query-performance

我有一个大约有12Mio记录的MySQL数据库。现在,我使用以下查询从该数据库查询所需的行:

SELECT date_time, price_l0, amount_l0, price_l1, amount_l1, price_l2, amount_l2, price_l3,  /* 34 more columns */
FROM book_states
WHERE date_time > ? and
      date_time < ? and
      bookID = ?
ORDER BY date_time ASC
LIMIT 4350

问题是,当我使用 LIMIT大约4340 时,此查询需要大约 0.002 / 0.15秒才能运行。但是,如果我使用的限制为 4350 ,则需要 3.0 / 0.15秒(!)才能运行。

如果我选择的列较少,则在非常快和非常慢的查询之间的阈值会略高,但是即使LIMIT大于5000,即使我仅选择一列,也要花费3秒或更长时间。

现在,我怀疑这是MySQL设置问题或某种形式的RAM限制,但是由于我无论如何都不是MySQL专家,所以我想请您解释一下导致此严重性能问题的原因。

编辑: 这是耗时3秒的JSON Explain数据

{
  "query_block": {
    "select_id": 1,
    "cost_info": {
      "query_cost": "282333.60"
    },
    "ordering_operation": {
      "using_filesort": true,
      "table": {
        "table_name": "book_states",
        "access_type": "ref",
        "possible_keys": [
          "index1",
          "index2",
          "index3"
        ],
        "key": "index2",
        "used_key_parts": [
          "bookID"
        ],
        "key_length": "2",
        "ref": [
          "const"
        ],
        "rows_examined_per_scan": 235278,
        "rows_produced_per_join": 81679,
        "filtered": "34.72",
        "index_condition": "(`datastore`.`book_states`.`bookID` <=> 29)",
        "cost_info": {
          "read_cost": "235278.00",
          "eval_cost": "16335.84",
          "prefix_cost": "282333.60",
          "data_read_per_join": "14M"
        },
        "used_columns": [
          "id",
          "date_time",
          "bookID"
        ],
        "attached_condition": "((`datastore`.`book_states`.`date_time` > '2018-09-28T16:18:49') and (`datastore`.`book_states`.`date_time` < '2018-09-29T23:18:49'))"
      }
    }
  }
}

1 个答案:

答案 0 :(得分:4)

您查询的最佳索引为:(bookID, date_time)。请注意列的顺序,这很重要。

MySQL正在努力优化现有索引的查询。它可以使用您提到的索引的date_time部分(或使用bookId)上的索引来选择记录,然后对结果进行排序。

或者,它可以扫描您的复合索引(按日期/时间排序的记录),从而过滤掉不需要的书籍。

在这两种方法之间进行选择(大概)。哪个更好取决于所收集的统计信息,并且它们必然仅提供部分信息。

因此,切换索引中的列,至少对于此特定查询而言,问题应该消失了。