"SELECT COUNT(*)" работает медленно, даже с предложением where

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

взгляните на эту ссылку, вы не можете сомневаться , чтобы понять, как работает оператор-идентификатор

43
задан Ovid 5 February 2009 в 01:25
поделиться

7 ответов

Кластеризируемые первичные ключи использования InnoDB, таким образом, первичный ключ хранится наряду со строкой в страницах данных, не в отдельных индексных страницах. Чтобы сделать, диапазон сканирует Вас, все еще должны просканировать через все потенциально широкие строки в страницах данных; обратите внимание, что эта таблица содержит Столбец текста.

Две вещи я попробовал бы:

  1. работает optimize table. Это гарантирует, что страницы данных физически хранятся в отсортированном порядке. Это могло очевидно ускорить сканирование диапазона на кластеризованном первичном ключе.
  2. создают дополнительный непервичный индекс на просто change_event_id столбце. Это сохранит копию того столбца в индексных страницах, которые быть намного быстрее для сканирования. После создания его проверьте объяснить план удостовериться, что это использует новый индекс.

(Вы также, вероятно, хотите сделать change_event_id столбец bigint неподписанным , если он увеличивает от нуля)

46
ответ дан ʞɔıu 4 August 2019 в 19:55
поделиться

Выполненный" analyze table_name" на той таблице - возможно, что индексы больше не оптимальны.

можно часто говорить это путем выполнения" show index from table_name". Если значение кардинальности NULL затем, необходимо вызвать переанализ.

1
ответ дан Alnitak 4 August 2019 в 19:55
поделиться

Вот несколько вещей, которые я предлагаю:

  • Изменение столбец от "bigint" до "неподписанного интервала". Вы действительно когда-либо ожидаете иметь больше чем 4,2 миллиарда записей в этой таблице? В противном случае затем Вы тратите впустую пространство (и время) общедополнительное поле. Индексы MySQL более эффективны на меньших типах данных.

  • Выполнение" ОПТИМИЗИРУЕТ ТАБЛИЦУ " команда и видит, является ли Ваш запрос немного быстрее позже.

  • Вы могли бы также рассмотреть разделение Вашей таблицы согласно полю ID, особенно если более старые записи (с более низкими Значениями идентификаторов) становятся менее релевантными со временем. Разделенная таблица может часто выполнять агрегатные запросы быстрее, чем одна огромная, неразделенная таблица.

<час>

РЕДАКТИРОВАНИЕ:

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

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

14
ответ дан Community 4 August 2019 в 19:55
поделиться

Я столкнулся с поведением как это прежде с базами данных геолокации IP. Прошлый некоторое количество записей, способность MySQL получить любое преимущество от индексов для основанных на диапазоне запросов, по-видимому, испаряется. С геолокацией DBS мы обработали его путем сегментации данных на блоки, которые были достаточно разумны позволить индексам использоваться.

5
ответ дан chaos 4 August 2019 в 19:55
поделиться

Проверьте, чтобы видеть, насколько фрагментированный Ваши индексы. В моей компании у нас есть ночной процесс импорта, который повреждает наши индексы, и со временем она может оказать глубокое влияние на скорости доступа к данным. Например, у нас была процедура SQL, которая заняла 2 часа для выполнения спустя один день за дефрагментацией индексов, потребовалось 3 минуты. мы используем SQL Server, 2005 плохо ищет сценарий, который может проверить это на MySQL.

Обновление: Проверьте эту ссылку: http://dev.mysql.com/doc/refman/5.0/en/innodb-file-defragmenting.html

3
ответ дан Random Developer 4 August 2019 в 19:55
поделиться

Я составил бы таблицу "счетчиков" и добавил бы, "создают строку" / "удаляют строку" триггеры к таблице, которую Вы считаете. Триггеры должны увеличиться/уменьшить значения количества на таблице "счетчиков" на каждом вставляемые/удалять, таким образом, Вы не должны будете вычислять их каждый раз, когда Вам нужны они.

можно также выполнить это на стороне приложения путем кэширования счетчиков, но это включит очистку "встречного кэша" на каждой вставке/удалении.

Для некоторой ссылки смотрят на этот http://pure.rednoize.com/2007/04/03/mysql-performance-use-counter-tables/

0
ответ дан knoopx 4 August 2019 в 19:55
поделиться

MySQL сначала говорит «Использование where», поскольку для их фактического подсчета необходимо прочитать все записи / значения из данных индекса. С InnoDb он также пытается «захватить» этот диапазон записей размером 4 мил для его подсчета.

Возможно, вам придется поэкспериментировать с различными уровнями изоляции транзакций: http://dev.mysql.com/doc/refman/5.1 /en/set-transaction.html#isolevel_read-uncommitted

и посмотрите, какой из них лучше.

С MyISAM это будет просто быстро, но при интенсивной модели записи возникнут проблемы с блокировкой.

1
ответ дан 26 November 2019 в 22:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: