MySql запрос в 1000 раз медленнее, с небольшим увеличением LIMIT (без смещения) - PullRequest
0 голосов
/ 01 октября 2018

У меня есть база данных MySQL с записями около 12 миллионов.Теперь я использую следующий запрос для запроса необходимых строк из этой базы данных:

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 секунды (!).

Если я выберу меньше столбцов, то пороговое значение будет оченьбыстрый и очень медленный запрос немного выше, но он занимает 3 секунды или более, даже если я выбираю только один столбец, если LIMIT выше 5000.

Теперь я подозреваю, что это проблема установки MySQL или какая-то оперативная памятьограничение, но, поскольку я ни в коем случае не являюсь экспертом MySQL, я прошу вас объяснить, что вызывает эту резкую проблему с производительностью.

РЕДАКТИРОВАТЬ: это данные JSON Explain для запроса, который занимает 3 секунды

{
  "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 голосов
/ 01 октября 2018

Лучший индекс для вашего запроса: (bookID, date_time).Обратите внимание на порядок столбцов, это очень важно.

MySQL пытается оптимизировать ваш запрос с помощью имеющихся индексов.Он может выбирать записи, используя часть date_time упомянутого вами индекса (или используя индекс на bookId), а затем сортировать результаты.

, или он может сканировать ваш составной индекс (в котором упорядочены записипо дате / времени), отфильтровывая ненужные книги по ходу дела.

Выбор между этими двумя методами - это то, что вы (предположительно) видите. Что лучше зависит от собранной статистики, и они обязательно предоставляют только частичныеинформация.

Итак, переключите столбцы в индексе, и проблема должна исчезнуть, по крайней мере, для этого конкретного запроса.

...