Подсчет общего количества таблиц является обычным бизнес-требованием в нашей разработке.Обычно мы используемselect count(*) from t
Оператор SQL для завершения. С увеличением объема бизнес-данных вы обнаружите, что скорость выполнения этого оператора становится все медленнее и медленнее. Почему она медленнее?
Почему это медленно? Чтобы получить ответ, вам нужно знать, как MySQL считает общее число.Давайте сначала поговорим о предпосылке.count(*)
Конкретная реализация реализуется подсистемой хранения, то есть разные подсистемы хранения реализуются по-разному. Название: Почемуselect count( * ) from t
, медленнее, чем MyISAM в движке InnoDB? Это также часто задаваемый вопрос на собеседовании.
InnoDB и MyISAM — наши часто используемые механизмы хранения MySQL, поэтому мы в основном сравниваем их.count(*)
Реализация в InnoDB и MyISAM:
- В механизме хранения MyISAM общее количество строк в таблице хранится на диске, и когда выполняется select count(*) from t, общие данные возвращаются напрямую..
- В механизме хранения InnoDB, в отличие от MyISAM, общее количество строк не хранится на диске, при выполнении select count(*) from t данные будут сначала считаны, накоплены построчно, и, наконец, общее количество будет вернулся.
Зная реализацию InnoDB и MyISAM engine count(*), почемуselect count(*) from t
, медленнее, чем MyISAM в движке InnoDB? Ответ должен быть, но для этого вывода нужна предпосылка, то есть статистический SQL не имеет условий фильтрации. Если оператор статистики SQL:select count(*) from t where x = 23
, то это не обязательно быстрее, чем InnoDB в MyISAM.
Выполняется оператор count(*) в InnoDB, при полном сканировании таблицы подсчитывается общее число, поэтому, когда данных становится все больше и больше, выполнение оператора становится все более и более трудоемким., почему механизм InnoDB не сохраняет общее количество строк на диск, как это делает механизм MyISAM? Это связано с транзакционным характером InnoDB.Из-за управления параллелизмом с несколькими версиями (MVCC) «сколько строк должно быть возвращено» в таблице InnoDB также неясно.
Для иллюстрации рассмотрим пример: предположим, что сейчас в таблице t 10 000 фрагментов данных, и три пользователя одновременно получают доступ к трем сеансам:
- Сеанс А запускает транзакцию и один раз запрашивает общее количество строк таблицы.
- Сеанс B запускает транзакцию, вставляет строку и записывает общее количество строк в таблицу запросов.
- Сеанс C запускает один оператор, вставляет строку, а затем запрашивает общее количество строк в таблице.
Предполагается, что выполнение выполняется в хронологическом порядке сверху вниз, и одна и та же строка операторов выполняется одновременно. Видно, что в последний момент общее количество строк, возвращаемых тремя сеансами, неодинаково.
Различные результаты связаны с механизмом хранения InnoDB.В случае повторяющегося чтения на уровне изоляции по умолчанию это реализовано через многоверсионный контроль параллелизма (MVCC).Каждая строка записей должна определять, видима ли она для этого сеанса.Поэтому при подсчете общего количества InnoDB имеет чтобы прочитать данные построчно.Выньте его, чтобы судить, в статистику включаются только те, которые видны в текущем сеансе. Поэтому количество запросов из разных сессий одновременно разное.
Движок InnoDBcount(*)
Оператор также был оптимизирован. Мы знаем, что в механизме хранения InnoDB данные хранятся в форме индексно-организованных таблиц. Листовые узлы в дереве индексов первичного ключа хранят все данные, в то время как листовые узлы обычного индексного дерева являются значением первичного ключа, поэтому обычное индексное дерево будет намного меньше, чем первичное индексное дерево, но число будет таким же, то есть результаты, полученные путем обхода индексного дерева первичного ключа и обычного индексного дерева, тоже самое. MySQL использует эту функцию и выполняет в InnoDB.select count(*) from t
При выполнении оператора оптимизатор MySQL найдет наименьшее дерево индексов для обхода, что может уменьшить количество загрузок и повысить эффективность выполнения count(*) в определенной степени.
В конце концов
В настоящее время многие крупные ребята в Интернете имеют статьи, связанные с MySQL.Если есть какие-либо сходства, пожалуйста, потерпите меня. Нелегко быть оригинальным, и нелегко кодировать слова, я также надеюсь, что вы поддержите это. Если в тексте будут ошибки, надеюсь сообщить о них, спасибо.